vue 实现模态框
使用 Vue 实现模态框
在 Vue 中实现模态框可以通过组件化方式完成,以下是一个完整的实现方案,包含基础功能、动画和自定义内容支持。
基础模态框组件实现
创建 Modal.vue 组件文件:
<template>
<div class="modal-overlay" v-if="isVisible" @click.self="close">
<div class="modal-content">
<slot></slot>
<button @click="close">关闭</button>
</div>
</div>
</template>
<script>
export default {
props: {
isVisible: {
type: Boolean,
required: true
}
},
methods: {
close() {
this.$emit('update:isVisible', false)
}
}
}
</script>
<style>
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content {
background: white;
padding: 20px;
border-radius: 8px;
max-width: 80%;
}
</style>
在父组件中使用模态框
<template>
<div>
<button @click="showModal = true">打开模态框</button>
<Modal :isVisible="showModal" @update:isVisible="showModal = $event">
<h3>自定义标题</h3>
<p>这里是模态框的内容</p>
</Modal>
</div>
</template>
<script>
import Modal from './Modal.vue'
export default {
components: { Modal },
data() {
return {
showModal: false
}
}
}
</script>
添加动画效果
修改 Modal.vue 增加过渡动画:
<template>
<transition name="fade">
<div class="modal-overlay" v-if="isVisible" @click.self="close">
<transition name="slide">
<div class="modal-content">
<slot></slot>
<button @click="close">关闭</button>
</div>
</transition>
</div>
</transition>
</template>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
.slide-enter-active, .slide-leave-active {
transition: transform 0.3s;
}
.slide-enter, .slide-leave-to {
transform: translateY(-50px);
}
</style>
支持自定义头部和底部
增强 Modal.vue 支持具名插槽:
<template>
<transition name="fade">
<div class="modal-overlay" v-if="isVisible" @click.self="close">
<transition name="slide">
<div class="modal-content">
<header v-if="$slots.header">
<slot name="header"></slot>
</header>
<slot></slot>
<footer v-if="$slots.footer">
<slot name="footer"></slot>
</footer>
</div>
</transition>
</div>
</transition>
</template>
使用具名插槽:
<Modal :isVisible="showModal" @update:isVisible="showModal = $event">
<template v-slot:header>
<h3>自定义标题</h3>
</template>
<p>主要内容区域</p>
<template v-slot:footer>
<button @click="doSomething">确认</button>
<button @click="close">取消</button>
</template>
</Modal>
通过 provide/inject 实现深层控制
对于复杂场景,可以使用 Vue 的依赖注入:
<script>
// 在 Modal.vue 中
export default {
provide() {
return {
modal: {
close: this.close
}
}
}
}
// 在深层子组件中
export default {
inject: ['modal'],
methods: {
handleAction() {
this.modal.close()
}
}
}
</script>
使用 Teleport 优化 DOM 结构
Vue 3 可以使用 Teleport 将模态框渲染到 body 末尾:
<template>
<teleport to="body">
<transition name="fade">
<!-- 模态框内容 -->
</transition>
</teleport>
</template>
注意事项
- 模态框通常需要设置
z-index确保在最上层 - 考虑添加 ESC 键关闭功能
- 打开模态框时可能需要禁用页面滚动
- 对于复杂场景可以考虑使用 Vue 插件如
vue-js-modal







