Dialog 对话框

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

基础用法

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

需要设置 model-value / v-model 属性,它接收 Boolean,当为 true 时显示 Dialog。 Dialog 分为两个部分:bodyfooterfooter 需要具名为 footerslottitle 属性用于定义标题,它是可选的,默认值为空。 最后,本例还展示了 before-close 的用法。

Dialog 对话框 - 图1

  1. <template>
  2. <el-button text @click="dialogVisible = true"
  3. >click to open the Dialog</el-button
  4. >
  5. <el-dialog
  6. v-model="dialogVisible"
  7. title="Tips"
  8. width="30%"
  9. :before-close="handleClose"
  10. >
  11. <span>This is a message</span>
  12. <template #footer>
  13. <span class="dialog-footer">
  14. <el-button @click="dialogVisible = false">Cancel</el-button>
  15. <el-button type="primary" @click="dialogVisible = false"
  16. >Confirm</el-button
  17. >
  18. </span>
  19. </template>
  20. </el-dialog>
  21. </template>
  22. <script lang="ts" setup>
  23. import { ref } from 'vue'
  24. import { ElMessageBox } from 'element-plus'
  25. const dialogVisible = ref(false)
  26. const handleClose = (done: () => void) => {
  27. ElMessageBox.confirm('Are you sure to close this dialog?')
  28. .then(() => {
  29. done()
  30. })
  31. .catch(() => {
  32. // catch error
  33. })
  34. }
  35. </script>
  36. <style scoped>
  37. .dialog-footer button:first-child {
  38. margin-right: 10px;
  39. }
  40. </style>

TIP

before-close 只会在用户点击关闭按钮或者对话框的遮罩区域时被调用。 如果你在 footer 具名插槽里添加了用于关闭 Dialog 的按钮,那么可以在按钮的点击回调函数里加入 before-close 的相关逻辑。

自定义内容

对话框的内容可以是任何东西,甚至是一个表格或表单。 此示例显示如何在 Dialog 中使用 Element Plus 的表格和表单。

Dialog 对话框 - 图2

  1. <template>
  2. <el-button text @click="dialogTableVisible = true"
  3. >open a Table nested Dialog</el-button
  4. >
  5. <el-dialog v-model="dialogTableVisible" title="Shipping address">
  6. <el-table :data="gridData">
  7. <el-table-column property="date" label="Date" width="150" />
  8. <el-table-column property="name" label="Name" width="200" />
  9. <el-table-column property="address" label="Address" />
  10. </el-table>
  11. </el-dialog>
  12. <!-- Form -->
  13. <el-button text @click="dialogFormVisible = true"
  14. >open a Form nested Dialog</el-button
  15. >
  16. <el-dialog v-model="dialogFormVisible" title="Shipping address">
  17. <el-form :model="form">
  18. <el-form-item label="Promotion name" :label-width="formLabelWidth">
  19. <el-input v-model="form.name" autocomplete="off" />
  20. </el-form-item>
  21. <el-form-item label="Zones" :label-width="formLabelWidth">
  22. <el-select v-model="form.region" placeholder="Please select a zone">
  23. <el-option label="Zone No.1" value="shanghai" />
  24. <el-option label="Zone No.2" value="beijing" />
  25. </el-select>
  26. </el-form-item>
  27. </el-form>
  28. <template #footer>
  29. <span class="dialog-footer">
  30. <el-button @click="dialogFormVisible = false">Cancel</el-button>
  31. <el-button type="primary" @click="dialogFormVisible = false"
  32. >Confirm</el-button
  33. >
  34. </span>
  35. </template>
  36. </el-dialog>
  37. </template>
  38. <script lang="ts" setup>
  39. import { reactive, ref } from 'vue'
  40. const dialogTableVisible = ref(false)
  41. const dialogFormVisible = ref(false)
  42. const formLabelWidth = '140px'
  43. const form = reactive({
  44. name: '',
  45. region: '',
  46. date1: '',
  47. date2: '',
  48. delivery: false,
  49. type: [],
  50. resource: '',
  51. desc: '',
  52. })
  53. const gridData = [
  54. {
  55. date: '2016-05-02',
  56. name: 'John Smith',
  57. address: 'No.1518, Jinshajiang Road, Putuo District',
  58. },
  59. {
  60. date: '2016-05-04',
  61. name: 'John Smith',
  62. address: 'No.1518, Jinshajiang Road, Putuo District',
  63. },
  64. {
  65. date: '2016-05-01',
  66. name: 'John Smith',
  67. address: 'No.1518, Jinshajiang Road, Putuo District',
  68. },
  69. {
  70. date: '2016-05-03',
  71. name: 'John Smith',
  72. address: 'No.1518, Jinshajiang Road, Putuo District',
  73. },
  74. ]
  75. </script>
  76. <style scoped>
  77. .el-button--text {
  78. margin-right: 15px;
  79. }
  80. .el-select {
  81. width: 300px;
  82. }
  83. .el-input {
  84. width: 300px;
  85. }
  86. .dialog-footer button:first-child {
  87. margin-right: 10px;
  88. }
  89. </style>

自定义头部

header 可用于自定义显示标题的区域。 为了保持可用性,除了使用此插槽外,使用 title 属性,或使用 titleId 插槽属性来指定哪些元素应该读取为对话框标题。

Dialog 对话框 - 图3

  1. <template>
  2. <el-button @click="visible = true">
  3. Open Dialog with customized header
  4. </el-button>
  5. <el-dialog v-model="visible" :show-close="false">
  6. <template #header="{ close, titleId, titleClass }">
  7. <div class="my-header">
  8. <h4 :id="titleId" :class="titleClass">This is a custom header!</h4>
  9. <el-button type="danger" @click="close">
  10. <el-icon class="el-icon--left"><CircleCloseFilled /></el-icon>
  11. Close
  12. </el-button>
  13. </div>
  14. </template>
  15. This is dialog content.
  16. </el-dialog>
  17. </template>
  18. <script lang="ts" setup>
  19. import { ref } from 'vue'
  20. import { ElButton, ElDialog } from 'element-plus'
  21. import { CircleCloseFilled } from '@element-plus/icons-vue'
  22. const visible = ref(false)
  23. </script>
  24. <style scoped>
  25. .my-header {
  26. display: flex;
  27. flex-direction: row;
  28. justify-content: space-between;
  29. }
  30. </style>

嵌套的对话框

如果需要在一个 Dialog 内部嵌套另一个 Dialog,需要使用 append-to-body 属性。

通常我们不建议使用嵌套对话框。 如果你需要在页面上呈现多个对话框,你可以简单地打平它们,以便它们彼此之间是平级关系。 将内层 Dialog 的该属性设置为 true,它就会插入至 body 元素上,从而保证内外层 Dialog 和遮罩层级关系的正确。

Dialog 对话框 - 图4

  1. <template>
  2. <el-button text @click="outerVisible = true">open the outer Dialog</el-button>
  3. <el-dialog v-model="outerVisible" title="Outer Dialog">
  4. <template #default>
  5. <el-dialog
  6. v-model="innerVisible"
  7. width="30%"
  8. title="Inner Dialog"
  9. append-to-body
  10. />
  11. </template>
  12. <template #footer>
  13. <div class="dialog-footer">
  14. <el-button @click="outerVisible = false">Cancel</el-button>
  15. <el-button type="primary" @click="innerVisible = true"
  16. >open the inner Dialog</el-button
  17. >
  18. </div>
  19. </template>
  20. </el-dialog>
  21. </template>
  22. <script lang="ts" setup>
  23. import { ref } from 'vue'
  24. const outerVisible = ref(false)
  25. const innerVisible = ref(false)
  26. </script>
  27. <style scoped>
  28. .dialog-footer button:first-child {
  29. margin-right: 10px;
  30. }
  31. </style>

内容居中

标题和底部可水平居中

center设置为true即可使标题和底部居中。 center仅影响标题和底部区域。 Dialog 的内容是任意的,在一些情况下,内容并不适合居中布局。 如果需要内容也水平居中,请自行为其添加 CSS 样式。

Dialog 对话框 - 图5

  1. <template>
  2. <el-button text @click="centerDialogVisible = true"
  3. >Click to open the Dialog</el-button
  4. >
  5. <el-dialog v-model="centerDialogVisible" title="Warning" width="30%" center>
  6. <span
  7. >It should be noted that the content will not be aligned in center by
  8. default</span
  9. >
  10. <template #footer>
  11. <span class="dialog-footer">
  12. <el-button @click="centerDialogVisible = false">Cancel</el-button>
  13. <el-button type="primary" @click="centerDialogVisible = false"
  14. >Confirm</el-button
  15. >
  16. </span>
  17. </template>
  18. </el-dialog>
  19. </template>
  20. <script lang="ts" setup>
  21. import { ref } from 'vue'
  22. const centerDialogVisible = ref(false)
  23. </script>
  24. <style scoped>
  25. .dialog-footer button:first-child {
  26. margin-right: 10px;
  27. }
  28. </style>

TIP

Dialog 的内容是懒渲染的——在被第一次打开之前,传入的默认 slot 不会被立即渲染到 DOM 上。 因此,如果需要执行 DOM 操作,或通过 ref 获取相应组件,请在 open 事件回调中进行。

居中对话框

从屏幕中心打开对话框。

设置 align-centertrue 使对话框水平垂直居中。 由于对话框垂直居中在弹性盒子中,所以top属性将不起作用。

Dialog 对话框 - 图6

  1. <template>
  2. <el-button text @click="centerDialogVisible = true"
  3. >Click to open the Dialog</el-button
  4. >
  5. <el-dialog
  6. v-model="centerDialogVisible"
  7. title="Warning"
  8. width="30%"
  9. align-center
  10. >
  11. <span>Open the dialog from the center from the screen</span>
  12. <template #footer>
  13. <span class="dialog-footer">
  14. <el-button @click="centerDialogVisible = false">Cancel</el-button>
  15. <el-button type="primary" @click="centerDialogVisible = false"
  16. >Confirm</el-button
  17. >
  18. </span>
  19. </template>
  20. </el-dialog>
  21. </template>
  22. <script lang="ts" setup>
  23. import { ref } from 'vue'
  24. const centerDialogVisible = ref(false)
  25. </script>
  26. <style scoped>
  27. .dialog-footer button:first-child {
  28. margin-right: 10px;
  29. }
  30. </style>

可拖拽对话框

试着拖动一下header部分吧

设置draggable属性为true以做到拖拽

Dialog 对话框 - 图7

  1. <template>
  2. <el-button text @click="dialogVisible = true"
  3. >Click to open Dialog
  4. </el-button>
  5. <el-dialog v-model="dialogVisible" title="Tips" width="30%" draggable>
  6. <span>It's a draggable Dialog</span>
  7. <template #footer>
  8. <span class="dialog-footer">
  9. <el-button @click="dialogVisible = false">Cancel</el-button>
  10. <el-button type="primary" @click="dialogVisible = false"
  11. >Confirm</el-button
  12. >
  13. </span>
  14. </template>
  15. </el-dialog>
  16. </template>
  17. <script lang="ts" setup>
  18. import { ref } from 'vue'
  19. const dialogVisible = ref(false)
  20. </script>

TIP

modal 的值为 false 时,请一定要确保 append-to-body 属性为 true,由于 Dialog 使用 position: relative 定位,当外层的遮罩层被移除时,Dialog 则会根据当前 DOM 上的祖先节点来定位,因此可能造成定位问题。

属性

属性说明类型可选值默认值
model-value / v-model是否显示 Dialogboolean
titleDialog 对话框 Dialog 的标题, 也可通过具名 slot (见下表)传入string
widthDialog 的宽度string / number50%
fullscreen是否为全屏 Dialogbooleanfalse
topDialog CSS 中的 margin-top 值string15vh
modal是否需要遮罩层booleantrue
append-to-bodyDialog 自身是否插入至 body 元素上。 嵌套的 Dialog 必须指定该属性并赋值为 truebooleanfalse
lock-scroll是否在 Dialog 出现时将 body 滚动锁定booleantrue
custom-classdeprecatedDialog 的自定义类名string
open-delayDialog 打开的延时时间,单位毫秒number0
close-delayDialog 关闭的延时时间,单位毫秒number0
close-on-click-modal是否可以通过点击 modal 关闭 Dialogbooleantrue
close-on-press-escape是否可以通过按下 ESC 关闭 Dialogbooleantrue
show-close是否显示关闭按钮booleantrue
before-close关闭前的回调,会暂停 Dialog 的关闭function(done),done 用于关闭 Dialog
draggable为 Dialog 启用可拖拽功能booleanfalse
center是否让 Dialog 的 header 和 footer 部分居中排列booleanfalse
align-center是否水平垂直对齐对话框booleanfalse
destroy-on-close当关闭 Dialog 时,销毁其中的元素booleanfalse

WARNING

custom-class 已被 废弃,将于版本 2.3.0时移除,请使用class

插槽

插槽名说明
Dialog 的内容
header对话框标题的内容;会替换标题部分,但不会移除关闭按钮。
titledeprecated与 header 作用相同 请使用 header
footerDialog 按钮操作区的内容

事件

事件名说明参数
openDialog 打开的回调
openedDialog 打开动画结束时的回调
closeDialog 关闭的回调
closedDialog 关闭动画结束时的回调
open-auto-focus输入焦点聚焦在 Dialog 内容时的回调
close-auto-focus输入焦点从 Dialog 内容失焦时的回调

源代码

组件 Dialog 对话框 - 图8 文档 Dialog 对话框 - 图9

贡献者

Dialog 对话框 - 图10 三咲智子

Dialog 对话框 - 图11 JeremyWuuuuu

Dialog 对话框 - 图12 云游君

Dialog 对话框 - 图13 bqy_fe

Dialog 对话框 - 图14 Aex

Dialog 对话框 - 图15 류한경

Dialog 对话框 - 图16 Delyan Haralanov

Dialog 对话框 - 图17 zz

Dialog 对话框 - 图18 LIUCHAO

Dialog 对话框 - 图19 opengraphica

Dialog 对话框 - 图20 renovate[bot]

Dialog 对话框 - 图21 C.Y.Kun

Dialog 对话框 - 图22 hfutsora

Dialog 对话框 - 图23 btea

Dialog 对话框 - 图24 FunkyZc

Dialog 对话框 - 图25 Hefty

Dialog 对话框 - 图26 kooriookami

Dialog 对话框 - 图27 spx

Dialog 对话框 - 图28 Alan Wang

Dialog 对话框 - 图29 msidolphin

Dialog 对话框 - 图30 on the field of hope

Dialog 对话框 - 图31 zazzaz

Dialog 对话框 - 图32 Hades-li