vue模态框通过默认插槽、具名插槽、作用域插槽和teleport实现自由组合:默认插槽承载主体内容,具名插槽定制头部/底部,作用域插槽传递内部状态(如loading),teleport将dom渲染至body以隔离样式与z-index。

默认插槽放主体内容
不带 name 的 <slot></slot> 就是默认插槽,适合承载业务核心区域。比如表单、提示文案、图片预览等。
- 父组件直接在
<modal></modal>标签内写内容,就会自动注入到这个位置 - 支持响应式绑定(
v-model)和事件监听(@click),插槽内逻辑照常运行 - 避免在 Modal 内部写死
<div class="body"> 这类结构,样式和语义交给调用方更灵活 <h3>具名插槽控制头部和底部</h3> <p>通过 <code>name属性定义多个插槽,让头部、底部等固定区域可独立定制。-
<slot name="header"></slot>:可塞入带关闭图标、拖拽手柄或自定义标题的任意结构 -
<slot name="footer"></slot>:替代“确定/取消”,适配“保存并发布”“跳过”“上传中…”等场景 - 配合
v-if或 props 动态控制是否渲染某块区域,比如仅编辑态显示 footer
作用域插槽传递内部状态
当需要把 Modal 内部的状态(如 loading 状态、关闭权限)暴露给外部时,用作用域插槽。
- 在 Modal 中写:
<slot name="footer" :loading="isSubmitting"></slot> - 父组件使用:
<template loading><button :disabled="loading">提交</button></template> - 这样既能复用 Modal 的控制逻辑,又能由外部决定 UI 行为
搭配 Teleport 隔离 DOM 结构
模态框需脱离当前组件层级渲染到 body 下,避免样式污染和 z-index 冲突。
- 用
<teleport to="body"></teleport>包裹整个 Modal 结构 - 确保遮罩层和弹窗 DOM 在顶层,CSS 选择器不会被父级 scoped 影响
- 配合
@click.self实现点击遮罩关闭,逻辑清晰且不干扰子元素事件
-










