Skip to content

Dialog 弹窗

在 element-plus 弹窗组件基础上封装,更适合业务快速开发。

TIP

  • 点击取消按钮默认关闭弹窗
  • 弹窗默认可以拖拽,不支持点击遮罩层关闭弹窗(可以自定义修改)

常规弹窗

<script lang="ts" setup>
import { ref } from 'vue'

const isShowDialog = ref(false)
</script>

<template>
  <el-button link type="primary" @click="isShowDialog = true">
    点击打开 Dialog
  </el-button>
  <z-dialog
    v-model="isShowDialog"
    title="标题"
    @confirm="isShowDialog = false"
  >
    <span>这是一段信息</span>
  </z-dialog>
</template>

信息、警告、错误弹窗

type传入infowarningdanger即可

<script lang="ts" setup>
import { ref } from 'vue'

const isShowInfoDialog = ref(false)
const isShowWarningDialog = ref(false)
const isShowDangerDialog = ref(false)
</script>

<template>
  <el-button link type="primary" @click="isShowInfoDialog = true">
    信息弹窗
  </el-button>
  <el-button link type="primary" @click="isShowWarningDialog = true">
    警告弹窗
  </el-button>
  <el-button link type="primary" @click="isShowDangerDialog = true">
    错误弹窗
  </el-button>
  <z-dialog
    v-model="isShowInfoDialog"
    type="info"
    title="信息"
    @confirm="isShowInfoDialog = false"
  >
    <span>这是一段信息</span>
  </z-dialog>
  <z-dialog
    v-model="isShowWarningDialog"
    type="warning"
    title="警告"
    @confirm="isShowWarningDialog = false"
  >
    <span>这是一段信息</span>
  </z-dialog>
  <z-dialog
    v-model="isShowDangerDialog"
    type="danger"
    title="错误"
    @confirm="isShowDangerDialog = false"
  >
    <span>这是一段信息</span>
  </z-dialog>
</template>

导入用法

支持通过方法调用打开弹窗,内部会默认配置标题。 我们可以通过titlemessage或者函数的参数传入字符串实现自定义标题和内容。

TIP

因为文档的渲染原因,ZDialogTip函数直接绑定在了window上,如果您在项目中使用,可以直接从ideaz-element包中导入。

<script lang="ts" setup>
import { h } from 'vue'

function openInfoDialog() {
  window.ZDialogTip({
    type: 'info',
    message: '提示信息',
    onConfirm: ({ done, confirmButtonLoading }) => {
      confirmButtonLoading.value = true
      done()
    },
    onCancel: ({ done }) => {
      done()
    },
  })
}

function openWarningDialog() {
  window.ZDialogTip.warning('提示信息', '标题', {
    type: 'warning',
    onConfirm: ({ confirmButtonLoading }) => {
      confirmButtonLoading.value = true
    },
    onCancel: ({ done }) => {
      done()
    },
  })
}

function openDangerDialog() {
  window.ZDialogTip({
    type: 'danger',
    message: () => h('span', {}, 'custom message'),
    title: () => h('span', {}, 'custom title'),
    onConfirm: ({ confirmButtonLoading }) => {
      confirmButtonLoading.value = true
    },
    onCancel: ({ done }) => {
      done()
    },
  })
}
</script>

<template>
  <el-button link type="primary" @click="openInfoDialog">
    信息弹窗
  </el-button>
  <el-button link type="primary" @click="openWarningDialog">
    警告弹窗
  </el-button>
  <el-button link type="primary" @click="openDangerDialog">
    错误弹窗
  </el-button>
</template>

操作按钮

  • 使用confirmButtonLabelconfirmButtonLoadingcancelButtonLabelcancelButtonLoading属性配置按钮文案和加载状态
  • 使用confirmButtonPropscancelButtonProps属性配置弹窗按钮所有属性
  • 函数模式的onConfirmonCancel接收一个对象,包含done方法和按钮状态,调用done方法可以关闭弹窗,修改按钮状态可以实现按钮的loading效果
<script lang="ts" setup>
import { reactive, ref } from 'vue'

const isShowDialog = ref(false)
const isShow = ref(false)

const confirmButtonProps = reactive({
  label: '确认按钮',
  type: 'danger',
  loading: false,
})

const cancelButtonProps = reactive({
  label: '取消按钮',
  type: 'primary',
  loading: false,
})

const isConfirmBtnLoading = ref(false)
const isCancelBtnLoading = ref(false)

function openWarningDialog() {
  window.ZDialogTip({
    type: 'warning',
    message: '警告信息',
    onConfirm: async ({ done, confirmButtonLoading }) => {
      confirmButtonLoading.value = true
      await delay(200)
      confirmButtonLoading.value = false
      done()
    },
    onCancel: async ({ done, cancelButtonLoading }) => {
      cancelButtonLoading.value = true
      await delay(200)
      cancelButtonLoading.value = false
      done()
    },
  })
}

async function handleConfirm() {
  confirmButtonProps.loading = true
  try {
    await delay(200)
    confirmButtonProps.loading = false
    isShowDialog.value = false
  }
  catch {}
  confirmButtonProps.loading = false
}

async function handleCancel() {
  cancelButtonProps.loading = true
  try {
    await delay(200)
    cancelButtonProps.loading = false
    isShowDialog.value = false
  }
  catch {}
  cancelButtonProps.loading = false
}

async function confirm() {
  isConfirmBtnLoading.value = true
  try {
    await delay(200)
    isConfirmBtnLoading.value = false
    isShow.value = false
  }
  catch {}
  isConfirmBtnLoading.value = false
}

async function cancel() {
  isCancelBtnLoading.value = true
  try {
    await delay(200)
    isCancelBtnLoading.value = false
    isShow.value = false
  }
  catch {}
  isCancelBtnLoading.value = false
}

function delay(time: number) {
  return new Promise((resolve) => {
    setTimeout(resolve, time)
  })
}
</script>

<template>
  <el-button link type="primary" @click="openWarningDialog">
    事件配置
  </el-button>
  <el-button link type="primary" @click="isShowDialog = true">
    对象属性配置
  </el-button>
  <el-button link type="primary" @click="isShow = true">
    常规属性配置
  </el-button>
  <z-dialog
    v-model="isShowDialog"
    title="标题"
    :confirm-button-props="confirmButtonProps"
    :cancel-button-props="cancelButtonProps"
    @confirm="handleConfirm"
    @cancel="handleCancel"
  >
    <span>这是一段信息</span>
  </z-dialog>
  <z-dialog
    v-model="isShow"
    title="标题"
    confirm-button-label="确认按钮"
    cancel-button-label="取消按钮"
    :confirm-button-loading="isConfirmBtnLoading"
    :cancel-button-loading="isCancelBtnLoading"
    @confirm="confirm"
    @cancel="cancel"
  >
    <span>这是一段信息</span>
  </z-dialog>
</template>

标题自定义

可以使用title插槽或者render函数自定义标题

<script lang="ts" setup>
import { h, ref } from 'vue'

const isShowDialog = ref(false)
const isShowRenderDialog = ref(false)

function renderTitle() {
  return h('span', 'render标题')
}

function handleClick() {
  window.ZDialogTip({
    type: 'danger',
    message: () => h('span', {}, 'custom message'),
    title: () => h('span', {}, 'custom title'),
    onConfirm: ({ done, confirmButtonLoading }) => {
      confirmButtonLoading.value = true
      done()
    },
    onCancel: ({ done, cancelButtonLoading }) => {
      cancelButtonLoading.value = true
      done()
      cancelButtonLoading.value = false
    },
  })
}
</script>

<template>
  <el-button link type="primary" @click="isShowDialog = true">
    点击打开slot Dialog
  </el-button>
  <el-button link type="primary" @click="isShowRenderDialog = true">
    点击打开render Dialog
  </el-button>
  <el-button link type="primary" @click="handleClick">
    点击打开render Dialog
  </el-button>
  <z-dialog
    v-model="isShowDialog"
    @confirm="isShowDialog = false"
  >
    <template #title>
      插槽标题
    </template>
    <span>这是一段信息</span>
  </z-dialog>
  <z-dialog
    v-model="isShowRenderDialog"
    :title="renderTitle"
    @confirm="isShowRenderDialog = false"
  >
    <span>这是一段信息</span>
  </z-dialog>
</template>

底部按钮自定义

传入footer插槽或者render函数自定义底部按钮,footer传入false可关闭底部按钮。

<script lang="ts" setup>
import { h, ref } from 'vue'

const isShowDialog = ref(false)
const isShowRenderDialog = ref(false)
const isShowFooterDialog = ref(false)

function renderFooter() {
  return h('div', 'render底部')
}
</script>

<template>
  <ElButton link type="primary" @click="isShowDialog = true">
    点击打开slot Dialog
  </ElButton>
  <ElButton link type="primary" @click="isShowRenderDialog = true">
    点击打开render Dialog
  </ElButton>
  <ElButton link type="primary" @click="isShowFooterDialog = true">
    点击打开footer Dialog
  </ElButton>
  <z-dialog
    v-model="isShowDialog"
    title="标题"
  >
    <template #footer>
      <ElButton size="default" @click="isShowDialog = false">
        关闭弹窗
      </ElButton>
    </template>
    <span>这是一段信息</span>
  </z-dialog>
  <z-dialog
    v-model="isShowRenderDialog"
    title="标题"
    :footer="renderFooter"
  >
    <span>这是一段信息</span>
  </z-dialog>
  <z-dialog
    v-model="isShowFooterDialog"
    title="标题"
    :footer="false"
  >
    <span>这是一段信息</span>
  </z-dialog>
</template>

before-close

关闭前回调

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'

const isShowDialog = ref(false)

function handleConfirm(done: () => void) {
  console.log(done, 'sdf')
}

async function handleBeforeClose(done: () => void) {
  console.log('handleBeforeClose')
  await delay(200)
  done()
}

function handleOpen() {
  isShowDialog.value = true
}

function openDialog() {
  window.ZDialogTip({
    type: 'warning',
    message: '内容',
    title: '标题',
    beforeClose: (done) => {
      console.log('before close extend')
      done()
    },
    onConfirm: ({ confirmButtonLoading }) => {
      confirmButtonLoading.value = true
    },
    onCancel: ({ done }) => {
      done()
    },
  })
}

function handleClose() {
  console.log('handleClose')
}

function delay(time: number) {
  return new Promise((resolve) => {
    setTimeout(resolve, time)
  })
}
</script>

<template>
  <el-button link type="primary" @click="handleOpen">
    点击打开 Dialog
  </el-button>
  <el-button link type="primary" @click="openDialog">
    点击打开 Dialog
  </el-button>
  <z-dialog
    v-model="isShowDialog"
    type="warning"
    :before-close="handleBeforeClose"
    @closed="handleClose"
    @confirm="handleConfirm"
  >
    <template #header>
      <span>slotTitle</span>
    </template>
    <span>这是一段信息</span>
  </z-dialog>
</template>

z-dialog属性

属性名说明类型默认
model-value / v-model是否显示 Dialogboolean
titleDialog 对话框 Dialog 的标题string / () => VNode''
typeDialog 的类型normal / info / warning / danger'normal'
footer自定义 Dialog 底部() => VNode''
confirmButtonLabel确认按钮文案string'确认'
confirmButtonLoading确认按钮加载状态booleanfalse
confirmButtonProps确认按钮属性object
cancelButtonLabel取消按钮文案string'取消'
cancelButtonLoading取消按钮加载状态booleanfalse
cancelButtonProps取消按钮属性object
width对话框的宽度,默认值为 50%string / number''
fullscreen是否为全屏 Dialogbooleanfalse
topdialog CSS 中的 margin-top 值,默认为 15vhstring''
modal是否需要遮罩层booleantrue
modal-class遮罩的自定义类名string
append-to-bodyDialog 自身是否插入至 body 元素上。 嵌套的 Dialog 必须指定该属性并赋值为 truebooleanfalse
lock-scroll是否在 Dialog 出现时将 body 滚动锁定booleantrue
custom-class deprecatedDialog 的自定义类名string''
open-delaydialog 打开的延时时间,单位毫秒number0
close-delaydrawer 关闭的延时时间,单位毫秒number0
close-on-click-modal是否可以通过点击 modal 关闭 Dialogbooleantrue
close-on-press-escape是否可以通过按下 ESC 关闭 Dialogbooleantrue
show-close是否显示关闭按钮booleantrue
before-close关闭前的回调,会暂停 Dialog 的关闭. 回调函数内执行 done 参数方法的时候才是真正关闭对话框的时候.Function
draggable为 Dialog 启用可拖拽功能booleanfalse
center是否让 Dialog 的 header 和 footer 部分居中排列booleanfalse
align-center 2.2.16是否水平垂直对齐对话框booleanfalse
destroy-on-close当关闭 Dialog 时,销毁其中的元素booleanfalse
close-icon自定义关闭图标,默认 Closestring / Component
z-index和原生的 CSS 的 z-index 相同,改变 z 轴的顺序number
header-aria-level a11yheader 的 aria-level 属性string2

z-dialog插槽

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

z-dialog事件

事件名说明Type
openDialog 打开的回调Function
openedDialog 打开动画结束时的回调Function
closeDialog 关闭的回调Function
closedDialog 关闭动画结束时的回调Function
open-auto-focus输入焦点聚焦在 Dialog 内容时的回调Function
close-auto-focus输入焦点从 Dialog 内容失焦时的回调Function
confirm点击确定按钮的回调Function
cancel点击取消按钮的回调Function

Released under the MIT License.