Skip to content

弹出框(原生)

基于 HTML5 原生 <dialog> 元素封装的弹出框组件。它保留了 TechUI 的视觉风格,利用浏览器原生特性实现了模态层管理。

基础用法

使用 v-model 控制显示状态。

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

const visible = ref(false)
</script>

<template>
  <TuiButton @click="visible = true">打开原生 Dialog</TuiButton>

  <TuiDialogNative 
    v-model="visible" 
    title="原生标题"
  >
    <div class="dialog-content">
      这是一个基于 native &lt;dialog&gt; 的组件。
    </div>
  </TuiDialogNative>
</template>

视觉风格

与标准 TuiDialog 组件一样,TuiDialogNative 也集成了 TuiTyped 系统。你可以轻松定义语义化色调或高级视觉效果(如磨砂玻璃)。

语义色调

支持 primary, success, warning, danger 等常用语义。

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

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

<template>
  <TuiButton type="primary" @click="state.primary = true">Primary</TuiButton>
  <TuiButton type="danger" @click="state.danger = true">Danger</TuiButton>

  <TuiDialogNative v-model="state.primary" title="Primary" type="primary">
    主要色调内容
  </TuiDialogNative>

  <TuiDialogNative v-model="state.danger" title="Danger" type="danger">
    危险色调内容
  </TuiDialogNative>
</template>

高级配置 (TypedConfig)

通过 typedConfig 开启半透明或调整色调强度。

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

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

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

  <TuiDialogNative
    v-model="visible"
    title="Glass Style"
    type="success"
    :typedConfig="glassConfig"
  >
    利用原生 Dialog 实现的磨砂玻璃效果。
  </TuiDialogNative>
</template>

尺寸与布局

原生组件同样支持灵活的尺寸定义,支持 pxvwvh 等单位。

  • width: 定义宽度 (如 40vw, 500)。
  • top: 定义距离顶部的偏移 (如 30vh, -200)。
  • fullscreen: 开启全屏模式。
vue
<script setup>
import { reactive } from 'vue'

const state = reactive({
  custom: false,
  full: false
})
</script>

<template>
  <TuiButton @click="state.custom = true">自定义宽高</TuiButton>
  <TuiButton @click="state.full = true">全屏展示</TuiButton>

  <TuiDialogNative 
    v-model="state.custom" 
    title="自定义 Layout" 
    width="40vw"
    top="30vh"
  >
    宽度 40vw,距离顶部 30vh。
  </TuiDialogNative>

  <TuiDialogNative v-model="state.full" title="全屏" fullscreen>
    全屏内容
  </TuiDialogNative>
</template>

嵌套弹窗

支持在原生 Dialog 中嵌套打开另一个原生 Dialog,组件内部会自动管理层级。

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

const state = reactive({
  layer1: false,
  layer2: false
})
</script>

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

  <TuiDialogNative v-model="state.layer1" title="Layer 1" width="500">
    <p>第一层内容...</p>
    <TuiButton @click="state.layer2 = true">打开第二层</TuiButton>
  </TuiDialogNative>

  <TuiDialogNative v-model="state.layer2" title="Layer 2" width="300">
    <p>第二层内容,堆叠在上方。</p>
  </TuiDialogNative>
</template>

API 参考

Props

属性名说明类型默认值
modelValue(v-model) 是否显示 DialogBooleanfalse
title标题文本String''
width弹窗宽度,支持 500(px) 或 '40vw'String / Numbernull
top距离顶部的偏移量,支持 200(px) 或 '30vh'String / Numbernull
fullscreen是否全屏显示Booleanfalse
modal是否启用模态模式 (显示遮罩)Booleantrue
center内容是否居中Booleanfalse
type语义类型,可选 `'default''primary''success'
typedConfigTuiTyped 配置对象 (transparent, tone, backgroundBlur)Object
customColor自定义颜色String / Array
showClose是否显示关闭图标Booleantrue
closeIcon自定义关闭图标 ClassString'tui-icon ti-times'
divider是否显示标题分割线Booleanfalse
closeOnBackdrop点击背景遮罩是否关闭Booleantrue
closeOnEsc按下 ESC 键是否关闭Booleantrue
overflow是否允许内容溢出Booleanfalse
customClass自定义类名String''

Emits

事件名说明回调参数
update:modelValue绑定值变化时触发value: boolean
open打开时触发
opened打开动画结束时触发
close关闭时触发
closed关闭动画结束时触发
confirm点击确认按钮触发 (需配合 Footer 使用)

Expose

组件通过 ref 暴露了以下属性和方法,可用于直接操作 DOM。

名称说明类型
open手动打开方法() => void
close手动关闭方法() => void
dialogRef原生 <dialog> 元素的 DOM 引用HTMLDialogElement
baseDialogRef内部包装容器的引用HTMLElement

全局交互与层级管控

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

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