Dialog 对话框
在保留当前页面上下文的前提下向用户展示信息或收集操作。
基础用法
弹层对话框,可高度定制。
使用布尔类型的 model-value / v-model 控制显示;为 true 时展示。对话框分为 body 与 footer,底部内容放在名为 footer 的插槽中。可选 title 定义标题(默认为空)。本例同时演示 before-close 的用法。
TIP
before-close 仅在点击关闭图标或遮罩时生效。若在 footer 插槽中放置关闭按钮,请在对应点击逻辑中自行处理与 before-close 相同的行为。
自定义内容
内容可为任意结构,例如表格或表单。本例演示与 Uniboot UI 表格、表单组合使用。
自定义头部
使用 header 插槽自定义标题区域。为兼顾无障碍,请同时设置 title 属性,或通过插槽属性 titleId 指定作为对话框标题朗读的元素。
嵌套对话框
对话框嵌套时需设置 append-to-body。
一般不推荐嵌套;若页面需多个对话框,可平铺为同级节点。若必须嵌套,请将内层对话框的 append-to-body 设为 true,使其挂到 body 而非父节点,以保证层级与样式正确。
居中布局
可将标题与底部操作区水平居中。
center 为 true 时,标题与底部水平居中;仅影响头部与底部,正文区域需自行编写样式居中。
TIP
对话框内容采用懒渲染:首次打开前默认插槽不会挂载到 DOM。若需操作 DOM 或通过 ref 访问子组件,请在 open 事件回调中执行。
屏幕居中
自屏幕中央打开对话框。
align-center 为 true 时水平、垂直居中;此时 top 不再生效,因垂直方向由 Flex 居中。
关闭时销毁
开启后,默认插槽内容在关闭时通过 v-if 销毁,适合有性能顾虑的场景。
注意开启后,在 transition.beforeEnter 触发前正文不会渲染,初始仅有遮罩与(若有)头部、底部。
可拖拽对话框
拖拽标题栏区域移动。
draggable 为 true 可拖拽;overflow 为 true 时允许拖出视口一定范围。
TIP
当 modal 为 false 时,请务必将 append-to-body 设为 true:Dialog 使用 position: relative 定位,去掉遮罩后会相对当前 DOM 位置而非 document.body 定位,易导致样式错乱。
全屏
设置 fullscreen 以全屏展示。
TIP
fullscreen 为 true 时,width、top、draggable 均不生效。
头部图标
在对话框标题前显示图标,增强视觉提示效果。
通过 show-header-icon 控制是否显示图标,header-icon 设置图标(支持图标名称或组件),header-icon-class 自定义图标样式。
遮罩层
modal 为 false 时不显示遮罩。
支持 modal-penetrable,可允许事件穿透。
自定义动画
通过 transition 自定义过渡,可为:
过渡名称(字符串)
Vue
Transition配置对象
包含缩放、滑动、淡入淡出、弹跳等示例,以及带自定义钩子函数的对象写法。
TIP
动画类名会随过渡名称动态生成;若需细粒度控制,可自行声明相关类,详见 Vue 文档 custom-transition-classes。
事件顺序
打开浏览器开发者工具(Ctrl + Shift + J)可观察事件触发顺序。
API
属性
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| model-value / v-model | 是否显示 | boolean | false |
| title | 标题;也可通过具名插槽传入(见下表) | string | '' |
| width | 宽度,默认 50% | string / number | '' |
| fullscreen | 是否全屏 | boolean | false |
| top | 对话框 CSS margin-top,默认 15vh | string | '' |
| modal | 是否显示遮罩 | boolean | true |
| modal-penetrable | 遮罩是否可穿透;需将 modal 设为 false | boolean | false |
| modal-class | 遮罩自定义类名 | string | — |
| header-class | 头部包裹层类名 | string | — |
| body-class | 内容区包裹层类名 | string | — |
| footer-class | 底部包裹层类名 | string | — |
| append-to-body | 是否将对话框挂到 body;嵌套对话框应设为 true | boolean | false |
| append-to | 挂载目标元素;会覆盖 append-to-body | CSSSelector / HTMLElement | body |
| lock-scroll | 显示时是否锁定 body 滚动 | boolean | true |
| open-delay | 打开前延迟(毫秒) | number | 0 |
| close-delay | 关闭前延迟(毫秒) | number | 0 |
| close-on-click-modal | 点击遮罩是否关闭 | boolean | true |
| close-on-press-escape | 按 ESC 是否关闭 | boolean | true |
| show-close | 是否显示关闭按钮 | boolean | false |
| before-close | 关闭前回调;可调用传入的 done 关闭;若需阻止关闭则不调用 | Function | — |
| draggable | 是否可拖拽 | boolean | false |
| overflow | 可拖拽时是否允许超出视口 | boolean | false |
| center | 标题与底部是否水平居中 | boolean | false |
| align-center | 对话框是否在视口水平、垂直居中 | boolean | false |
| destroy-on-close | 关闭时是否销毁默认插槽内容 | boolean | false |
| close-icon | 自定义关闭图标,默认 Close | string / Component | — |
| z-index | 同原生 z-index | number | — |
| header-aria-level a11y | 头部 aria-level | string | 2 |
| transition | 自定义过渡:过渡名字符串或 Vue TransitionProps 对象 | string / object | dialog-fade |
| show-header-icon | 是否显示头部图标 | boolean | false |
| header-icon | 头部图标 | string / Component | — |
| header-icon-class | 头部图标的自定义类名 | string | — |
WARNING
custom-class 已废弃,请改用 class。
插槽
| 名称 | 说明 |
|---|---|
| default | 默认内容 |
| header | 头部区域;替换后不再显示标题区文案,但关闭按钮仍保留 |
| footer | 底部区域 |
WARNING
title 插槽已废弃。
事件
| 名称 | 说明 | 类型 |
|---|---|---|
| open | 打开时触发 | Function |
| opened | 打开动画结束后触发 | Function |
| close | 关闭时触发 | Function |
| closed | 关闭动画结束后触发 | Function |
| open-auto-focus | 打开且内容聚焦后触发 | Function |
| close-auto-focus | 关闭且焦点处理后触发 | Function |
暴露
| 名称 | 说明 | 类型 |
|---|---|---|
| resetPosition | 重置位置 | Function |
| handleClose | 关闭对话框 | Function |
常见问题
在 SFC 中使用对话框时,scoped 样式不生效
典型讨论:#10515
说明:对话框通过 Teleport 渲染,根节点样式建议写在全局样式中。
对话框显示/隐藏时页面元素发生横向跳动
典型讨论:#10481
说明:建议将滚动区域放在 Vue 挂载根节点内(如 <div id="app" />),并对 body 使用 overflow: hidden 等策略。