用 script setup 实现弹窗轻量化控制:通过 useModal 组合函数封装单一 visible 状态,解构即用;子组件用 v-model:visible 接收,父组件免事件透传;多弹窗用独立 useModal 或 reactive 管理;Teleport 挂载至 body 且 v-show 控制显隐。

用 script setup 实现弹窗显示状态的轻量化控制,核心是“少声明、少传递、少耦合”——不依赖全局状态、不硬编码多个 ref 变量,靠组合式逻辑和合理作用域把显隐控制收得干净。
用 useModal 组合函数封装单一状态
把弹窗开关逻辑抽成可复用的 hook,避免每个组件都写 const visible = ref(false):
- 创建
useModal():内部只维护一个ref,返回visible、open、close三个基础能力 - 调用时直接解构,无需手动声明变量:
const { visible, open, close } = useModal() - 支持传参初始化(比如默认打开或带延迟关闭),但不强制——保持轻量,按需扩展
父组件中直接绑定 v-model,省去事件透传
弹窗组件用 v-model:visible 接收并响应,父组件不用监听 @update:visible 再手动赋值:
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
- 子组件 props 声明:
defineProps({ modelValue: Boolean }) - 模板中绑定:
<div v-show="modelValue">...</div> - 父组件使用:
<MyDialog v-model:visible="visible" />,开闭完全由visible控制
需要多弹窗时,用局部 ref + 函数式调用替代全局变量
一个页面多个弹窗,不堆 dialog1Visible、dialog2Visible 等一堆 ref:
立即学习“前端免费学习笔记(深入)”;
- 每个按钮独立调用
useModal(),状态彼此隔离 - 或者用
const modals = reactive({ a: false, b: false })统一管理,模板中绑定v-model:visible="modals.a" - 避免在 setup 顶层写多个 ref,既难维护,又容易误触发响应
配合 Teleport 提升体验,不增加状态负担
弹窗挂载到 body 下解决层级/遮罩问题,但不需要额外状态控制挂载位置:
- 直接在弹窗组件内用
<Teleport to="body">,不暴露挂载点参数 - 遮罩层用
v-show而非v-if,显隐切换更轻量,无重建开销 - 背景滚动锁定等副作用,在
watch(visible)中统一处理,不分散逻辑

















