vue自己实现dialog
实现自定义 Dialog 组件
封装基础 Dialog 组件
创建 Dialog.vue 文件,使用 v-model 控制显示状态,通过插槽支持内容自定义:
<template>
<div class="dialog-mask" v-if="visible" @click.self="close">
<div class="dialog-container">
<div class="dialog-header">
<slot name="header">{{ title }}</slot>
<button @click="close">×</button>
</div>
<div class="dialog-body">
<slot></slot>
</div>
<div class="dialog-footer">
<slot name="footer">
<button @click="close">取消</button>
<button @click="$emit('confirm')">确定</button>
</slot>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
visible: Boolean,
title: String
},
methods: {
close() {
this.$emit('update:visible', false)
}
}
}
</script>
<style scoped>
.dialog-mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
display: flex;
justify-content: center;
align-items: center;
}
.dialog-container {
background: white;
min-width: 300px;
border-radius: 4px;
overflow: hidden;
}
.dialog-header {
padding: 16px;
display: flex;
justify-content: space-between;
border-bottom: 1px solid #eee;
}
.dialog-body {
padding: 24px 16px;
}
.dialog-footer {
padding: 12px 16px;
text-align: right;
border-top: 1px solid #eee;
}
</style>
通过服务式调用
创建 dialog.js 服务文件实现动态调用:
import Vue from 'vue'
const DialogConstructor = Vue.extend(require('./Dialog.vue'))
function showDialog(options) {
const instance = new DialogConstructor({
propsData: options.props
})
if (options.parent) {
instance.$mount(options.parent.appendChild(document.createElement('div')))
} else {
document.body.appendChild(instance.$mount().$el)
}
return {
close: () => {
instance.visible = false
setTimeout(() => {
instance.$destroy()
instance.$el.remove()
}, 300)
}
}
}
export default {
install(Vue) {
Vue.prototype.$dialog = showDialog
}
}
全局注册使用
在 main.js 中安装插件:
import Dialog from './plugins/dialog'
Vue.use(Dialog)
组件调用示例
<template>
<button @click="show">打开弹窗</button>
</template>
<script>
export default {
methods: {
show() {
this.$dialog({
props: {
visible: true,
title: '提示'
}
})
}
}
}
</script>
模板调用示例
<Dialog v-model="visible" title="自定义标题">
<template #header>替换标题</template>
主体内容
<template #footer>
<button @click="visible = false">关闭</button>
</template>
</Dialog>
动画效果增强 添加过渡动画需修改样式:
.dialog-mask {
/* 原有样式 */
opacity: 0;
transition: opacity 0.3s;
}
.dialog-mask.v-enter-active,
.dialog-mask.v-leave-active {
opacity: 1;
}
.dialog-container {
transform: translateY(-20px);
transition: transform 0.3s;
}
.dialog-mask.v-enter-active .dialog-container,
.dialog-mask.v-leave-active .dialog-container {
transform: translateY(0);
}
注意事项
- 通过
z-index控制层级关系 - 防止背景滚动需添加
overflow: hidden到body - 服务式调用需手动管理组件销毁
- 可通过
provide/inject实现深层嵌套内容控制







