vue 实现弹窗组件
Vue 弹窗组件实现
基础弹窗组件结构
创建一个名为Modal.vue的文件,定义弹窗的基础结构和样式:
<template>
<div class="modal-mask" v-show="visible" @click.self="close">
<div class="modal-container">
<div class="modal-header">
<h3>{{ title }}</h3>
<button @click="close">×</button>
</div>
<div class="modal-body">
<slot></slot>
</div>
<div class="modal-footer">
<button @click="close">取消</button>
<button @click="confirm">确定</button>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
visible: Boolean,
title: String
},
methods: {
close() {
this.$emit('update:visible', false)
},
confirm() {
this.$emit('confirm')
this.close()
}
}
}
</script>
<style scoped>
.modal-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;
}
.modal-container {
background: white;
min-width: 300px;
border-radius: 4px;
overflow: hidden;
}
.modal-header {
padding: 16px;
display: flex;
justify-content: space-between;
border-bottom: 1px solid #eee;
}
.modal-body {
padding: 16px;
}
.modal-footer {
padding: 16px;
text-align: right;
border-top: 1px solid #eee;
}
</style>
使用弹窗组件
在父组件中注册并使用弹窗:
<template>
<div>
<button @click="showModal = true">打开弹窗</button>
<Modal
v-model:visible="showModal"
title="提示"
@confirm="handleConfirm"
>
<p>这是弹窗内容</p>
</Modal>
</div>
</template>
<script>
import Modal from './Modal.vue'
export default {
components: { Modal },
data() {
return {
showModal: false
}
},
methods: {
handleConfirm() {
console.log('用户点击了确定')
}
}
}
</script>
进阶功能实现
动态控制弹窗宽度 在Modal组件中添加width属性:

<script>
export default {
props: {
width: {
type: String,
default: 'auto'
}
}
}
</script>
<style scoped>
.modal-container {
width: v-bind(width);
}
</style>
添加动画效果 使用Vue的transition组件实现淡入淡出效果:
<template>
<transition name="fade">
<div class="modal-mask" v-show="visible" @click.self="close">
<!-- 其余内容不变 -->
</div>
</transition>
</template>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
全局弹窗服务 创建全局弹窗服务避免重复导入:

// modalService.js
import { createApp } from 'vue'
import Modal from './Modal.vue'
export default {
install(app) {
const modalInstance = createApp(Modal).mount(document.createElement('div'))
document.body.appendChild(modalInstance.$el)
app.config.globalProperties.$modal = {
show(options) {
Object.assign(modalInstance, options)
modalInstance.visible = true
return new Promise(resolve => {
modalInstance.$once('confirm', () => resolve(true))
modalInstance.$once('update:visible', val => !val && resolve(false))
})
}
}
}
}
在main.js中注册:
import modalService from './modalService.js'
const app = createApp(App)
app.use(modalService)
使用全局弹窗:
this.$modal.show({
title: '全局弹窗',
content: '这是全局弹窗内容'
}).then(confirmed => {
console.log(confirmed ? '用户确认' : '用户取消')
})






