Skip to content

对话框

在保留当前页面状态的情况下,告知用户并承载相关操作。

该组件内部集成了 TuiMask 处理遮罩层逻辑,并基于 TuiTyped 组件构建了强大的多色调与外观系统,能够灵活适应各种 UI 风格。

基础用法

Dialog 弹出一个对话框,适合需要定制性更大的场景。

vue
<script setup>
import { ref } from 'vue'

const visible = ref(false)
</script>

<template>
  <TuiButton @click="visible = true">打开常规 Dialog</TuiButton>

  <TuiDialog 
    v-model="visible" 
    title="常规标题"
  >
    <div class="dialog-content">
      这是一段基础内容。
    </div>
  </TuiDialog>
</template>

布局与尺寸

提供了丰富的属性来控制弹窗的显示位置和大小,支持百分比与像素值。

  • width: 自定义宽度(支持 40%300 像素值)。
  • fullscreen: 开启全屏显示。
  • alignCenter: 将弹窗垂直水平居中显示(默认为顶部 15vh 偏移)。
  • top: 自定义距离顶部的距离。
vue
<script setup>
import { reactive } from 'vue'

const state = reactive({
  showFull: false,
  showCenter: false,
  showCustom: false
})
</script>

<template>
  <div class="demo-box">
    <TuiButton @click="state.showFull = true">全屏展示</TuiButton>
    <TuiButton @click="state.showCenter = true">居中显示</TuiButton>
    <TuiButton @click="state.showCustom = true">自定义宽与Top</TuiButton>
  </div>

  <TuiDialog v-model="state.showFull" title="全屏展示" fullscreen>
    内容区域
  </TuiDialog>

  <TuiDialog v-model="state.showCenter" title="居中显示" alignCenter width="30%">
    内容区域垂直居中
  </TuiDialog>

  <TuiDialog 
    v-model="state.showCustom" 
    title="自定义样式" 
    width="40%" 
    top="200"
  >
    宽度 40%,距离顶部 200px
  </TuiDialog>
</template>

拖拽与定位

通过 draggable 属性可实现弹窗的拖拽功能。

  • draggable: 是否开启拖拽。
  • positionType: 定义定位策略,可选 transform (推荐, 性能更好)、absolutefixed
  • dragContainment: 限制拖拽范围在可视区域内。
  • resetDragOnClose: 关闭后是否重置位置。
vue
<script setup>
import { ref } from 'vue'

const visible = ref(false)
</script>

<template>
  <TuiButton @click="visible = true">打开可拖拽 Dialog</TuiButton>

  <TuiDialog
    v-model="visible"
    title="按住标题拖拽我"
    draggable
    positionType="transform"
    :resetDragOnClose="true"
  >
    <div>我使用了 transform 定位,拖拽更流畅。</div>
  </TuiDialog>
</template>

色调与风格

TuiDialog 深度集成了 TuiTyped 组件,通过 typetypedConfig 属性,您可以极其方便地配置弹窗的主题色调(如主要、警告、危险等)以及视觉风格(如透明、模糊背景、强弱色调)。

关于 TuiTyped:这是一个专门处理组件色调变体和视觉深度的底层原子组件,它允许组件在不同背景下自动计算最佳的前景色与背景色。

常用色调

通过 type 属性快速切换预设语义色。

vue
<script setup>
import { reactive } from 'vue'

const dialogs = reactive({
  primary: false,
  success: false,
  warning: false,
  danger: false
})
</script>

<template>
  <div class="demo-gap">
    <TuiButton type="primary" @click="dialogs.primary = true">Primary</TuiButton>
    <TuiButton type="success" @click="dialogs.success = true">Success</TuiButton>
    <TuiButton type="warning" @click="dialogs.warning = true">Warning</TuiButton>
    <TuiButton type="danger" @click="dialogs.danger = true">Danger</TuiButton>
  </div>

  <TuiDialog v-model="dialogs.primary" title="Primary" type="primary">Content</TuiDialog>
  <TuiDialog v-model="dialogs.success" title="Success" type="success">Content</TuiDialog>
  <TuiDialog v-model="dialogs.warning" title="Warning" type="warning">Content</TuiDialog>
  <TuiDialog v-model="dialogs.danger" title="Danger" type="danger">Content</TuiDialog>
</template>

高级风格配置 (TypedConfig)

通过 typedConfig 对象,可以控制更细粒度的视觉表现,例如色调强度 (tone) 和透明度 (transparent)。

vue
<script setup>
import { ref } from 'vue'

const visible = ref(false)
const glassConfig = {
  transparent: true,      // 开启半透明
  backgroundBlur: true,   // 开启背景模糊
  tone: 'strong'          // 强色调模式
}
</script>

<template>
  <TuiButton @click="visible = true">打开磨砂玻璃风格</TuiButton>

  <TuiDialog
    v-model="visible"
    title="高级风格"
    type="primary"
    :typedConfig="glassConfig"
  >
    这是一个带有背景模糊和半透明效果的 Dialog。
  </TuiDialog>
</template>

嵌套与多层级

支持在一个 Dialog 内部打开另一个 Dialog。TuiDialog 会自动处理层级关系。

vue
<script setup>
import { reactive } from 'vue'

const state = reactive({
  outer: false,
  inner: false
})

const handleOpenInner = () => {
  state.inner = true
}
</script>

<template>
  <TuiButton @click="state.outer = true">打开第一层</TuiButton>

  <TuiDialog v-model="state.outer" title="第一层 Dialog" width="40%">
    <div class="dialog-content">
      <p>点击下方按钮打开第二层嵌套。</p>
      <TuiButton @click="handleOpenInner">打开第二层</TuiButton>
    </div>
  </TuiDialog>

  <TuiDialog v-model="state.inner" title="第二层 Dialog" width="20%">
    <div class="dialog-content">
      这是最顶层的弹窗内容。
    </div>
  </TuiDialog>
</template>

API 参考

Props

属性名说明类型默认值
modelValue(v-model) 是否显示 DialogBooleanfalse
title标题文本String
width弹窗宽度,支持 300 (px) 或 '40%'String / Numbernull
top距离顶部的偏移量String / Number
alignCenter是否垂直居中显示Booleanfalse
center是否让弹窗内部的 Header 和 Content 居中对齐Booleanfalse
fullscreen是否全屏显示Booleanfalse
modal是否需要遮罩层Booleantrue
draggable是否开启头部拖拽Booleanfalse
positionType拖拽定位类型,可选 `'transform''absolute''fixed'`
dragContainment是否将拖拽限制在窗口范围内Booleantrue
resetDragOnClose关闭时是否重置拖拽位置Booleantrue
type语义类型,可选 `'default''primary''success'
typedConfigTuiTyped 配置对象,包含 tone, transparent, backgroundBlurObject
customColor自定义颜色值,支持 HEX 或 RGB 数组String / Array
showClose是否显示关闭图标Booleantrue
closeIcon自定义关闭图标的 ClassString'tui-icon ti-times'
divider是否显示标题与内容之间的分割线Booleanfalse
destroyOnClose关闭时是否销毁元素Booleanfalse
lockScroll是否锁定背景滚动Booleantrue
closeOnBackdrop点击遮罩层是否关闭Booleantrue
closeOnEsc按下 Esc 键是否关闭Booleantrue
zIndex手动控制层级Numbernull
appendTo指定挂载的 DOM 节点选择器String

Emits

事件名说明回调参数
update:modelValue绑定值变化时触发value: boolean
openDialog 打开时触发
openedDialog 打开动画结束时触发
closeDialog 关闭时触发
closedDialog 关闭动画结束时触发
confirm确认事件(通常结合 footer 插槽使用)

Slots

插槽名说明
defaultDialog 的主体内容
footerDialog 底部操作区内容

全局交互与层级管控

在多层弹窗嵌套或并存的复杂场景下,TuiDialog 依赖 TechUI 的全局服务(TuiService)来实现智能的堆叠管理:

  • ESC 响应 (escCounter):组件实时监听全局 ESC 信号。当 closeOnEsctrue 时,组件会响应该信号。
  • 智能堆叠判断 (Stack Management):全局服务维护着一个当前活跃弹窗的堆叠栈。当 ESC 触发时,组件会与全局服务进行通信,确保仅有关闭处于最顶层(即最后打开或 z-index 最高)的 Dialog 实例。这种机制完美解决了嵌套弹窗场景下的“误关”问题,保证了交互逻辑的清晰与安全。