Skip to content

Dialog 对话框

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

基础用法

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

vue
<template>
  <ExButton type="primary" @click="dialogVisible = true">打开对话框</ExButton>

  <ExDialog v-model="dialogVisible" title="提示">
    <p>这是一段信息</p>
    <p>这是另一段信息</p>
  </ExDialog>
</template>

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

const dialogVisible = ref(false);
</script>

自定义标题

通过 title 插槽可以自定义标题内容。

vue
<template>
  <ExButton type="primary" @click="dialogVisible = true">自定义标题</ExButton>

  <ExDialog v-model="dialogVisible">
    <template #title>
      <span style="color: var(--ex-color-neon-blue-500);"> 🎮 游戏设置 </span>
    </template>
    <template #icon>
      <img
        src="https://api.iconify.design/ri/settings-3-line.svg"
        alt="设置"
        width="24"
        height="24"
      />
    </template>
    <div>画质:超高</div>
    <div>帧率:144 FPS</div>
  </ExDialog>
</template>

不同类型

通过 type 属性可以设置不同类型的对话框。

vue
<template>
  <ExButton type="primary" @click="dialogVisible = true">主要对话框</ExButton>

  <ExDialog v-model="dialogVisible" title="主要对话框" type="primary">
    <template #icon>
      <img
        src="https://api.iconify.design/ri/information-line.svg"
        alt="信息"
        width="24"
        height="24"
      />
    </template>
    <p>这是一个主要类型的对话框。</p>
  </ExDialog>
</template>

不同尺寸

通过 size 属性可以设置不同尺寸的对话框。

vue
<template>
  <ExButton @click="dialogVisible = true">小尺寸</ExButton>

  <ExDialog v-model="dialogVisible" title="小尺寸对话框" size="small">
    <p>这是一个小尺寸的对话框。</p>
  </ExDialog>
</template>

自定义底部

通过 footer 插槽可以自定义底部内容。

vue
<template>
  <ExButton type="primary" @click="dialogVisible = true">自定义底部</ExButton>

  <ExDialog
    v-model="dialogVisible"
    title="确认操作"
    :confirm-loading="confirmLoading"
    @confirm="handleConfirm"
  >
    <p>您确定要执行此操作吗?</p>
  </ExDialog>
</template>

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

const dialogVisible = ref(false);
const confirmLoading = ref(false);

const handleConfirm = () => {
  confirmLoading.value = true;
  setTimeout(() => {
    confirmLoading.value = false;
    dialogVisible.value = false;
  }, 2000);
};
</script>

居中显示

设置 center 属性可以让对话框内容居中显示。

vue
<template>
  <ExButton type="primary" @click="dialogVisible = true">居中对话框</ExButton>

  <ExDialog v-model="dialogVisible" title="居中显示" center>
    <div style="text-align: center;">
      <div style="font-size: 48px;">🏆</div>
      <div>恭喜获胜!</div>
    </div>
  </ExDialog>
</template>

全屏对话框

设置 fullscreen 属性可以让对话框全屏显示。

vue
<template>
  <ExButton type="primary" @click="dialogVisible = true">全屏对话框</ExButton>

  <ExDialog v-model="dialogVisible" title="全屏对话框" fullscreen>
    <div>全屏内容</div>
  </ExDialog>
</template>

嵌套对话框

对话框可以嵌套使用。

vue
<template>
  <ExButton type="primary" @click="outerVisible = true">打开外层对话框</ExButton>

  <ExDialog v-model="outerVisible" title="外层对话框">
    <p>这是外层对话框的内容。</p>
    <ExButton type="primary" @click="innerVisible = true">打开内层对话框</ExButton>

    <ExDialog v-model="innerVisible" title="内层对话框" :z-index="1060">
      <p>这是内层对话框的内容。</p>
    </ExDialog>
  </ExDialog>
</template>

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

const outerVisible = ref(false);
const innerVisible = ref(false);
</script>

自定义关闭按钮

通过 close 插槽可以自定义关闭按钮。

vue
<template>
  <ExButton type="primary" @click="dialogVisible = true">自定义关闭按钮</ExButton>

  <ExDialog v-model="dialogVisible" title="自定义关闭">
    <template #close>
      <img
        src="https://api.iconify.design/ri/close-circle-line.svg"
        alt="关闭"
        width="20"
        height="20"
      />
    </template>
    <p>自定义关闭按钮</p>
  </ExDialog>
</template>

不显示底部

设置 :show-footer="false" 可以隐藏底部操作栏。

vue
<template>
  <ExButton type="primary" @click="dialogVisible = true">无底部对话框</ExButton>

  <ExDialog v-model="dialogVisible" title="纯内容展示" :show-footer="false">
    <p>这是一个纯内容展示的对话框。</p>
  </ExDialog>
</template>

关闭前回调

通过 before-close 属性可以在关闭前执行回调,返回 false 可以阻止关闭。

当前状态: 有未保存内容(阻止关闭)
vue
<template>
  <ExButton type="primary" @click="dialogVisible = true">打开对话框</ExButton>

  <ExDialog v-model="dialogVisible" title="编辑内容" :before-close="handleBeforeClose">
    <p>尝试关闭对话框,如果有未保存内容会被阻止。</p>
  </ExDialog>
</template>

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

const dialogVisible = ref(false);
const hasUnsavedChanges = ref(true);

const handleBeforeClose = async () => {
  // 如果有未保存的更改,阻止关闭
  if (hasUnsavedChanges.value) {
    console.log('有未保存的内容,阻止关闭');
    return false;
  }
  return true;
};
</script>

API

Dialog Props

属性说明类型默认值
model-value / v-model是否显示对话框booleanfalse
title对话框标题string''
size对话框尺寸'small' | 'medium' | 'large' | 'full''medium'
type对话框类型'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info''default'
show-close是否显示关闭按钮booleantrue
modal是否显示遮罩层booleantrue
close-on-click-modal是否可以通过点击遮罩层关闭booleantrue
close-on-press-escape是否可以通过按下 ESC 键关闭booleantrue
show-footer是否显示底部操作栏booleantrue
confirm-text确认按钮文本string'确认'
cancel-text取消按钮文本string'取消'
show-confirm是否显示确认按钮booleantrue
show-cancel是否显示取消按钮booleantrue
confirm-loading确认按钮加载状态booleanfalse
confirm-disabled确认按钮禁用状态booleanfalse
center是否居中显示booleanfalse
fullscreen是否全屏显示booleanfalse
lock-scroll是否锁定滚动booleantrue
custom-class自定义类名string''
modal-class遮罩层自定义类名string''
before-open对话框打开前的回调() => boolean | Promise<boolean>undefined
before-close对话框关闭前的回调() => boolean | Promise<boolean>undefined
z-index层级number1050
append-to-body是否追加到 bodybooleantrue
destroy-on-close是否在关闭时销毁内容booleanfalse
aria-label无障碍标签stringundefined

Dialog Events

事件名说明类型
update:model-value更新 modelValue(value: boolean) => void
open对话框打开时触发() => void
opened对话框打开动画结束时触发() => void
close对话框关闭时触发() => void
closed对话框关闭动画结束时触发() => void
confirm点击确认按钮时触发() => void
cancel点击取消按钮时触发() => void

Dialog Slots

插槽名说明
default对话框内容
title自定义标题
icon自定义图标
close自定义关闭按钮
footer自定义底部内容

Dialog Methods

方法名说明类型
open打开对话框() => void
close关闭对话框() => void
getElement获取对话框 DOM 元素() => HTMLDivElement | null

无障碍支持

  • 使用 role="dialog"aria-modal 属性
  • 支持 ESC 键关闭
  • 完整的 ARIA 标签支持
  • 支持屏幕阅读器
  • 自动锁定焦点在对话框内

主题定制

可以通过 CSS 变量自定义对话框样式:

css
:root {
  --ex-dialog-bg: var(--ex-color-bg-surface);
  --ex-dialog-border-color: var(--ex-color-border-primary);
  --ex-dialog-shadow: var(--ex-shadow-2xl);
  --ex-dialog-header-border: var(--ex-color-border-primary);
  --ex-dialog-footer-border: var(--ex-color-border-primary);
}