Vue3 + TypeScript 控制弹框及数据传输实现
·
Vue3 + TypeScript 控制弹框及数据传输实现
弹框组件封装
创建一个可复用的弹框组件 Modal.vue,使用 defineProps 和 defineEmits 进行类型定义:
<template>
<div v-if="visible" class="modal-mask">
<div class="modal-container">
<slot name="header"></slot>
<slot name="body"></slot>
<button @click="$emit('close')">关闭</button>
</div>
</div>
</template>
<script setup lang="ts">
defineProps<{
visible: boolean
}>()
defineEmits<{
(e: 'close'): void
}>()
</script>
父组件调用逻辑
在父组件中通过 ref 控制弹框显隐,并传递数据:
<template>
<button @click="showModal">打开弹框</button>
<Modal :visible="isVisible" @close="hideModal">
<template #header>
<h2>{{ modalData.title }}</h2>
</template>
<template #body>
<p>{{ modalData.content }}</p>
</template>
</Modal>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Modal from './Modal.vue'
interface ModalData {
title: string
content: string
}
const isVisible = ref(false)
const modalData = ref<ModalData>({
title: '默认标题',
content: '默认内容'
})
const showModal = (data: ModalData) => {
modalData.value = data
isVisible.value = true
}
const hideModal = () => {
isVisible.value = false
}
</script>
跨组件通信方案
对于复杂场景可使用 provide/inject:
// 父组件
import { provide, ref } from 'vue'
const modalControl = ref(false)
provide('modalControl', modalControl)
// 子组件
import { inject } from 'vue'
const modalVisible = inject<Ref<boolean>>('modalControl')
事件总线替代方案
安装 mitt 库实现全局事件:
npm install mitt
创建事件中心:
// eventBus.ts
import mitt from 'mitt'
type Events = {
'show-modal': { title: string; content: string }
}
export const emitter = mitt<Events>()
组件中使用:
// 发送方
emitter.emit('show-modal', { title: '测试', content: '内容' })
// 接收方
emitter.on('show-modal', (data) => {
modalData.value = data
isVisible.value = true
})
类型安全增强
为弹框组件添加完整的类型定义:
interface ModalProps {
visible: boolean
size?: 'sm' | 'md' | 'lg'
}
interface ModalEmits {
(e: 'close'): void
(e: 'confirm', payload: unknown): void
}
动态组件方案
使用 component :is 实现动态弹框内容:
<component :is="currentModal" v-bind="modalProps" @close="hideModal" />
注意事项
- 弹框组件应设置
z-index和定位样式 - 通过
@keyup.escape监听 ESC 键关闭 - 添加
beforeUnmount事件清理 - 使用
Teleport组件避免 DOM 层级问题
完整示例应包含样式处理和动画效果,可通过 transition 组件实现平滑的显隐过渡。这种实现方式在 Vue3 组合式 API 下具有更好的类型推断和代码组织能力。
更多推荐


所有评论(0)