Skip to content

Modal 模态框

模态对话框,在当前页面打开一个浮层,承载相关操作。

基础用法

最简单的用法。默认为中等尺寸(520px)。

vue
<template>
  <ExButton type="primary" @click="visible = true">打开模态框</ExButton>

  <ExModal v-model="visible" title="基础模态框">
    <p>这是模态框的内容</p>
  </ExModal>
</template>

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

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

不同类型

通过 type 属性可以设置不同类型的模态框,不同类型会有不同的边框颜色和发光效果。

vue
<template>
  <ExButton type="primary" @click="visible = true">主要模态框</ExButton>

  <ExModal v-model="visible" title="主要模态框" type="primary" size="medium">
    <template #icon>
      <img
        src="https://api.iconify.design/ri/information-line.svg"
        alt="信息"
        width="24"
        height="24"
      />
    </template>
    <p>这是一个主要类型的模态框,带有霓虹蓝色边框和发光效果。</p>
  </ExModal>
</template>

不同尺寸

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

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

  <ExModal v-model="visible" title="小尺寸模态框" size="small">
    <p>这是一个小尺寸的模态框。</p>
  </ExModal>
</template>

自定义宽度

通过 width 属性可以自定义模态框宽度。

vue
<template>
  <ExButton type="primary" @click="visible = true">自定义宽度</ExButton>

  <ExModal v-model="visibleWidth" title="自定义宽度" :width="800">
    <p>这个模态框的宽度是 800px。</p>
  </ExModal>
</template>

居中显示

设置 centered 属性可以让模态框垂直居中显示。

vue
<template>
  <ExButton type="primary" @click="visible = true">居中模态框</ExButton>

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

自定义按钮文字

通过 okTextcancelText 属性可以自定义按钮文字。

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

  <ExModal
    v-model="visible"
    title="删除确认"
    ok-text="删除"
    cancel-text="我再想想"
    ok-type="danger"
  >
    <p>确定要删除这条记录吗?</p>
  </ExModal>
</template>

自定义底部

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

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

  <ExModal v-model="visibleCustomFooter" title="自定义底部" size="medium">
    <p>这是一个自定义底部的模态框。</p>
    <template #footer>
      <ExButton type="default" @click="visibleCustomFooter = false">知道了</ExButton>
    </template>
  </ExModal>
</template>

确认加载状态

通过 confirmLoading 属性可以让确认按钮处于加载状态。需要配合 before-close 属性来阻止模态框自动关闭。

vue
<template>
  <ExButton type="primary" @click="visible = true">加载状态</ExButton>

  <ExModal 
    v-model="visible" 
    title="提交表单" 
    :confirm-loading="confirmLoading"
    :before-close="() => !confirmLoading"
    @ok="handleOk"
  >
    <p>点击确定按钮后,按钮会显示加载状态。</p>
    <p>2秒后自动关闭。</p>
  </ExModal>
</template>

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

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

const handleOk = () => {
  confirmLoading.value = true;
  // 模拟异步操作(如API请求)
  setTimeout(() => {
    confirmLoading.value = false;
    visible.value = false;  // 操作完成后关闭模态框
  }, 2000);
};
</script>

不可点击遮罩关闭

设置 :mask-closable="false" 可以禁止点击遮罩层关闭。

vue
<template>
  <ExButton type="primary" @click="visible = true">不可点击遮罩关闭</ExButton>

  <ExModal v-model="visible" title="重要提示" :mask-closable="false">
    <p>这个模态框不能通过点击遮罩层关闭。</p>
  </ExModal>
</template>

自定义样式

通过 bodyStyle 属性可以自定义内容区域样式。

vue
<template>
  <ExButton type="primary" @click="visible = true">自定义样式</ExButton>

  <ExModal
    v-model="visible"
    title="自定义样式"
    :body-style="{
      background: 'linear-gradient(135deg, rgba(0, 240, 255, 0.1), rgba(255, 0, 127, 0.1))',
      minHeight: '200px',
    }"
  >
    <div>自定义内容样式</div>
  </ExModal>
</template>

嵌套模态框

模态框可以嵌套使用。

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

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

    <ExModal v-model="innerVisible" title="内层模态框" :z-index="1010">
      <p>这是内层模态框的内容。</p>
    </ExModal>
  </ExModal>
</template>

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

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

API

属性说明类型默认值
model-value / v-model是否显示模态框booleanfalse
title模态框标题string''
size模态框尺寸'small' | 'medium' | 'large''medium'
type模态框类型'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info''default'
show-close是否显示关闭按钮booleantrue
mask是否显示遮罩层booleantrue
mask-closable是否可以通过点击遮罩层关闭booleantrue
keyboard是否可以通过按下 ESC 键关闭booleantrue
ok-text确认按钮文本string'确定'
cancel-text取消按钮文本string'取消'
ok-type确认按钮类型'default' | 'primary' | 'success' | 'warning' | 'danger''primary'
confirm-loading确认按钮加载状态booleanfalse
centered是否居中显示booleanfalse
width宽度string | numberundefined
z-index层级number1000
append-to-body是否追加到 bodybooleantrue
destroy-on-close是否在关闭时销毁内容booleanfalse
wrap-class-name包装器自定义类名string''
body-style内容区域自定义样式Record<string, string | number>undefined
before-close模态框关闭前的回调() => boolean | Promise<boolean>undefined
aria-label无障碍标签stringundefined
事件名说明类型
update:model-value更新 modelValue(value: boolean) => void
ok点击确定按钮时触发() => void
cancel点击取消按钮时触发() => void
after-close模态框关闭动画结束后触发() => void
插槽名说明
default模态框内容
title自定义标题
icon自定义图标
footer自定义底部内容
closeIcon自定义关闭按钮图标
方法名说明类型
getElement获取模态框 DOM 元素() => HTMLDivElement | null

无障碍支持

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

主题定制

可以通过 CSS 变量自定义模态框样式:

css
:root {
  --ex-modal-bg: var(--ex-color-bg-surface);
  --ex-modal-border-color: var(--ex-color-border-primary);
  --ex-modal-shadow: var(--ex-shadow-2xl);
  --ex-modal-mask-bg: rgba(0, 0, 0, 0.75);
}