介绍
提示或接收用户的确认。
代码演示
基础使用
使用 dialog 等方法显示对话框。
vue
<template>
<s-list card>
<s-list-item arrow hover title="显示提示框" @click="showAlert" />
<s-list-item arrow hover title="显示确定框" @click="showConfirm" />
<s-list-item arrow hover title="无标题" @click="showConfirmNoTitle" />
</s-list>
</template>
<script setup lang="ts">
import { dialog } from 'sard'
const showAlert = () => {
dialog.alert({
title: '提示',
message: '此功能暂时无法使用',
})
}
const showConfirm = () => {
dialog.confirm({
title: '提示',
message: '确定删除?',
})
}
const showConfirmNoTitle = () => {
dialog.confirm({
message: '孤村落日残霞,轻烟老树寒鸦,一点飞鸿影下。青山绿水,白草红叶黄花。',
})
}
</script>vue
<template>
<s-list card>
<s-list-item arrow hover title="显示提示框" @click="showAlert" />
<s-list-item arrow hover title="显示确定框" @click="showConfirm" />
<s-list-item arrow hover title="无标题" @click="showConfirmNoTitle" />
</s-list>
</template>
<script setup lang="js">
import { dialog } from 'sard'
const showAlert = () => {
dialog.alert({
title: '提示',
message: '此功能暂时无法使用',
})
}
const showConfirm = () => {
dialog.confirm({
title: '提示',
message: '确定删除?',
})
}
const showConfirmNoTitle = () => {
dialog.confirm({ message: '孤村落日残霞,轻烟老树寒鸦,一点飞鸿影下。青山绿水,白草红叶黄花。' })
}
</script>异步关闭
如果 beforeClose 返回 false 或 rejected 状态的 Promise 可阻止关闭。
vue
<template>
<s-list card>
<s-list-item arrow hover title="确定按钮异步关闭" @click="showAlert" />
<s-list-item arrow hover title="取消按钮异步关闭" @click="showConfirm" />
</s-list>
</template>
<script setup lang="ts">
import { dialog } from 'sard'
const showAlert = () => {
dialog.confirm({
title: '提示',
message: '点击确定按钮会在一秒钟后关闭',
beforeClose: (type, loading) => {
if (type === 'confirm') {
return new Promise<void>((resolve) => {
setTimeout(resolve, 1000)
})
}
if (loading.confirm) {
return false
}
},
})
}
const showConfirm = () => {
dialog.confirm({
title: '提示',
message: '点击取消按钮会在一秒钟后关闭',
beforeClose: (type, loading) => {
if (type === 'cancel') {
return new Promise<void>((resolve) => {
setTimeout(resolve, 1000)
})
}
if (loading.cancel) {
return false
}
},
})
}
</script>vue
<template>
<s-list card>
<s-list-item arrow hover title="确定按钮异步关闭" @click="showAlert" />
<s-list-item arrow hover title="取消按钮异步关闭" @click="showConfirm" />
</s-list>
</template>
<script setup lang="js">
import { dialog } from 'sard'
const showAlert = () => {
dialog.confirm({
title: '提示',
message: '点击确定按钮会在一秒钟后关闭',
beforeClose: (type, loading) => {
if (type === 'confirm') {
return new Promise((resolve) => {
setTimeout(resolve, 1e3)
})
}
if (loading.confirm) {
return false
}
},
})
}
const showConfirm = () => {
dialog.confirm({
title: '提示',
message: '点击取消按钮会在一秒钟后关闭',
beforeClose: (type, loading) => {
if (type === 'cancel') {
return new Promise((resolve) => {
setTimeout(resolve, 1e3)
})
}
if (loading.cancel) {
return false
}
},
})
}
</script>圆角按钮
buttonType 属性值为 round 可以将底部按钮显示为圆角的形式。
vue
<template>
<s-list card>
<s-list-item arrow hover title="显示提示框" @click="showAlert" />
<s-list-item arrow hover title="显示确定框" @click="showConfirm" />
</s-list>
</template>
<script setup lang="ts">
import { dialog } from 'sard'
const showAlert = () => {
dialog.alert({
title: '提示',
message: '此功能暂时无法使用',
buttonType: 'round',
})
}
const showConfirm = () => {
dialog.confirm({
title: '提示',
message: '确定删除?',
buttonType: 'round',
})
}
</script>vue
<template>
<s-list card>
<s-list-item arrow hover title="显示提示框" @click="showAlert" />
<s-list-item arrow hover title="显示确定框" @click="showConfirm" />
</s-list>
</template>
<script setup lang="js">
import { dialog } from 'sard'
const showAlert = () => {
dialog.alert({
title: '提示',
message: '此功能暂时无法使用',
buttonType: 'round',
})
}
const showConfirm = () => {
dialog.confirm({
title: '提示',
message: '确定删除?',
buttonType: 'round',
})
}
</script>有头部的
配置 headed 属性让对话框显示头部,此时的对话框更像一个模态框。
vue
<template>
<s-list card>
<s-list-item arrow hover title="显示提示框" @click="showAlert" />
<s-list-item arrow hover title="显示确定框" @click="showConfirm" />
<s-list-item arrow hover title="显示提示框-无标题" @click="showAlertNoTitle" />
<s-list-item arrow hover title="显示确定框-无标题" @click="showConfirmNoTitle" />
</s-list>
</template>
<script setup lang="ts">
import { dialog } from 'sard'
const showAlert = () => {
dialog.alert({
title: '提示',
message: '此功能暂时无法使用',
buttonType: 'round',
headed: true,
})
}
const showConfirm = () => {
dialog.confirm({
title: '提示',
message: '确定删除?',
buttonType: 'round',
headed: true,
})
}
const showAlertNoTitle = () => {
dialog.alert({
message: '此功能暂时无法使用',
buttonType: 'round',
headed: true,
})
}
const showConfirmNoTitle = () => {
dialog.confirm({
message: '确定删除?',
buttonType: 'round',
headed: true,
})
}
</script>vue
<template>
<s-list card>
<s-list-item arrow hover title="显示提示框" @click="showAlert" />
<s-list-item arrow hover title="显示确定框" @click="showConfirm" />
<s-list-item arrow hover title="显示提示框-无标题" @click="showAlertNoTitle" />
<s-list-item arrow hover title="显示确定框-无标题" @click="showConfirmNoTitle" />
</s-list>
</template>
<script setup lang="js">
import { dialog } from 'sard'
const showAlert = () => {
dialog.alert({
title: '提示',
message: '此功能暂时无法使用',
buttonType: 'round',
headed: true,
})
}
const showConfirm = () => {
dialog.confirm({
title: '提示',
message: '确定删除?',
buttonType: 'round',
headed: true,
})
}
const showAlertNoTitle = () => {
dialog.alert({
message: '此功能暂时无法使用',
buttonType: 'round',
headed: true,
})
}
const showConfirmNoTitle = () => {
dialog.confirm({
message: '确定删除?',
buttonType: 'round',
headed: true,
})
}
</script>自定义内容
对话框里面可以放置任何内容,例如以模态的方式展示一个表单,通常要配合 headed 属性一起使用。
vue
<template>
<s-list card>
<s-list-item arrow hover title="登录表单" @click="visible = true" />
</s-list>
<s-dialog v-model:visible="visible" title="登录" :before-close="beforeClose">
<s-form ref="formRef" :model="formState">
<s-form-item name="name" label="用户名" :rules="[{ required: true }]">
<s-input inlaid placeholder="请输入" v-model="formState.name" />
</s-form-item>
<s-form-item name="password" label="密码" :rules="[{ required: true }]">
<s-input type="password" inlaid placeholder="请输入" v-model="formState.password" />
</s-form-item>
</s-form>
</s-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { toast } from 'sard'
import { reactive } from 'vue'
const visible = ref(false)
const formRef = ref()
const formState = reactive({
name: '',
password: '',
})
const beforeClose = (type: string) => {
if (type === 'confirm') {
return formRef.value?.validate().then(() => {
toast(JSON.stringify(formState))
formRef.value?.reset()
})
}
}
</script>vue
<template>
<s-list card>
<s-list-item arrow hover title="登录表单" @click="visible = true" />
</s-list>
<s-dialog v-model:visible="visible" title="登录" :before-close="beforeClose">
<s-form ref="formRef" :model="formState">
<s-form-item name="name" label="用户名" :rules="[{ required: true }]">
<s-input inlaid placeholder="请输入" v-model="formState.name" />
</s-form-item>
<s-form-item name="password" label="密码" :rules="[{ required: true }]">
<s-input type="password" inlaid placeholder="请输入" v-model="formState.password" />
</s-form-item>
</s-form>
</s-dialog>
</template>
<script setup lang="js">
import { ref } from 'vue'
import { toast } from 'sard'
import { reactive } from 'vue'
const visible = ref(false)
const formRef = ref()
const formState = reactive({
name: '',
password: '',
})
const beforeClose = (type) => {
if (type === 'confirm') {
return formRef.value?.validate().then(() => {
toast(JSON.stringify(formState))
formRef.value?.reset()
})
}
}
</script>内容中包含弹出框
对话框底层的 Popup 组件包裹在 teleport 中,因此基于 Popup 的可弹出组件都可以相互嵌套使用,也可以放置在滚动元素里面。
vue
<template>
<s-list card>
<s-list-item arrow hover title="显示复杂的对话框" @click="visible = true" />
</s-list>
<s-dialog
v-model:visible="visible"
title="复杂的对话框"
:before-close="beforeClose"
popup-style="top: 50%"
>
<div class="overflow-y-auto" style="height: 60vh; margin-top: 1px; margin-bottom: 8px">
<s-form ref="formRef" :model="formModel">
<s-form-item name="name" label="Activity name" :rules="[{ required: true }]">
<s-input inlaid v-model="formModel.name" placeholder="Please input Activity name" />
</s-form-item>
<s-form-item name="region" label="Activity zone">
<s-picker-input
v-model="formModel.region"
placeholder="please select your zone"
title="please select your zone"
:columns="[
{
label: 'Zone one',
value: 'shanghai',
},
{
label: 'Zone two',
value: 'beijing',
},
]"
/>
</s-form-item>
<s-form-item name="date1" label="Activity time">
<s-datetime-picker-input v-model="formModel.date1" type="yMd" placeholder="Pick a date" />
</s-form-item>
<s-form-item name="date2" label="">
<s-datetime-picker-input v-model="formModel.date2" type="hms" placeholder="Pick a time" />
</s-form-item>
<s-form-item name="date3" label="Active date range">
<s-datetime-range-picker-input
v-model="formModel.date3"
type="hms"
:tabs="['start', 'end']"
placeholder="Pick a time"
/>
</s-form-item>
<s-form-item name="delivery" label="Instant delivery">
<s-switch v-model="formModel.delivery" />
</s-form-item>
<s-form-item name="type" label="Activity type">
<s-checkbox-input
v-model="formModel.type"
placeholder="Pick Activity type"
:options="[
{ label: 'Online activities', value: 'Online activities' },
{ label: 'Promotion activities', value: 'Promotion activities' },
{ label: 'Offline activities', value: 'Offline activities' },
{
label: 'Simple brand exposure',
value: 'Simple brand exposure',
},
]"
/>
</s-form-item>
<s-form-item name="resource" label="Resources">
<s-radio-input
v-model="formModel.resource"
placeholder="Pick Resources"
:options="[
{ label: 'Sponsor', value: 'Sponsor' },
{ label: 'Venue', value: 'Venue' },
]"
/>
</s-form-item>
<s-form-item name="desc" label="Activity form" label-valign="start">
<s-input
inlaid
v-model="formModel.desc"
type="textarea"
placeholder="Please input Activity form"
show-count
/>
</s-form-item>
</s-form>
</div>
</s-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { toast } from 'sard'
import { reactive } from 'vue'
const visible = ref(false)
const formRef = ref()
const formModel = reactive({
name: '',
region: '',
date1: undefined,
date2: undefined,
date3: undefined,
delivery: false,
type: [],
resource: '',
desc: '',
})
const beforeClose = (type: string) => {
if (type === 'confirm') {
return formRef.value?.validate().then(() => {
toast('提交成功!')
formRef.value?.reset()
})
}
}
</script>vue
<template>
<s-list card>
<s-list-item arrow hover title="显示复杂的对话框" @click="visible = true" />
</s-list>
<s-dialog
v-model:visible="visible"
title="复杂的对话框"
:before-close="beforeClose"
popup-style="top: 50%"
>
<div class="overflow-y-auto" style="height: 60vh; margin-top: 1px; margin-bottom: 8px">
<s-form ref="formRef" :model="formModel">
<s-form-item name="name" label="Activity name" :rules="[{ required: true }]">
<s-input inlaid v-model="formModel.name" placeholder="Please input Activity name" />
</s-form-item>
<s-form-item name="region" label="Activity zone">
<s-picker-input
v-model="formModel.region"
placeholder="please select your zone"
title="please select your zone"
:columns="[
{
label: 'Zone one',
value: 'shanghai',
},
{
label: 'Zone two',
value: 'beijing',
},
]"
/>
</s-form-item>
<s-form-item name="date1" label="Activity time">
<s-datetime-picker-input v-model="formModel.date1" type="yMd" placeholder="Pick a date" />
</s-form-item>
<s-form-item name="date2" label="">
<s-datetime-picker-input v-model="formModel.date2" type="hms" placeholder="Pick a time" />
</s-form-item>
<s-form-item name="date3" label="Active date range">
<s-datetime-range-picker-input
v-model="formModel.date3"
type="hms"
:tabs="['start', 'end']"
placeholder="Pick a time"
/>
</s-form-item>
<s-form-item name="delivery" label="Instant delivery">
<s-switch v-model="formModel.delivery" />
</s-form-item>
<s-form-item name="type" label="Activity type">
<s-checkbox-input
v-model="formModel.type"
placeholder="Pick Activity type"
:options="[
{ label: 'Online activities', value: 'Online activities' },
{ label: 'Promotion activities', value: 'Promotion activities' },
{ label: 'Offline activities', value: 'Offline activities' },
{
label: 'Simple brand exposure',
value: 'Simple brand exposure',
},
]"
/>
</s-form-item>
<s-form-item name="resource" label="Resources">
<s-radio-input
v-model="formModel.resource"
placeholder="Pick Resources"
:options="[
{ label: 'Sponsor', value: 'Sponsor' },
{ label: 'Venue', value: 'Venue' },
]"
/>
</s-form-item>
<s-form-item name="desc" label="Activity form" label-valign="start">
<s-input
inlaid
v-model="formModel.desc"
type="textarea"
placeholder="Please input Activity form"
show-count
/>
</s-form-item>
</s-form>
</div>
</s-dialog>
</template>
<script setup lang="js">
import { ref } from 'vue'
import { toast } from 'sard'
import { reactive } from 'vue'
const visible = ref(false)
const formRef = ref()
const formModel = reactive({
name: '',
region: '',
date1: undefined,
date2: undefined,
date3: undefined,
delivery: false,
type: [],
resource: '',
desc: '',
})
const beforeClose = (type) => {
if (type === 'confirm') {
return formRef.value?.validate().then(() => {
toast('提交成功!')
formRef.value?.reset()
})
}
}
</script>自定义按钮属性
使用 cancelProps 和 confirmProps 属性可以自定义取消和确定按钮组件的属性。
vue
<template>
<s-list card>
<s-list-item arrow hover title="显示提示框" @click="showAlert" />
<s-list-item arrow hover title="显示确定框" @click="showConfirm" />
</s-list>
</template>
<script setup lang="ts">
import { dialog } from 'sard'
const showAlert = () => {
dialog.alert({
title: '提示',
message: '此功能暂时无法使用',
confirmProps: {
color: 'warning',
variant: 'solid',
},
})
}
const showConfirm = () => {
dialog.confirm({
title: '提示',
message: '确定删除?',
confirmProps: {
color: 'danger',
},
})
}
</script>vue
<template>
<s-list card>
<s-list-item arrow hover title="显示提示框" @click="showAlert" />
<s-list-item arrow hover title="显示确定框" @click="showConfirm" />
</s-list>
</template>
<script setup lang="js">
import { dialog } from 'sard'
const showAlert = () => {
dialog.alert({
title: '提示',
message: '此功能暂时无法使用',
confirmProps: {
color: 'warning',
variant: 'solid',
},
})
}
const showConfirm = () => {
dialog.confirm({
title: '提示',
message: '确定删除?',
confirmProps: { color: 'danger' },
})
}
</script>API
DialogProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| visible | 是否可见 | boolean | false |
| title | 标题 | string | - |
| message | 文本内容 | string | - |
| headed | 是否显示带头部类型 | boolean | true |
| button-type | 按钮类型 | 'round' | 'text' | 'round' |
| show-cancel | 是否显示取消按钮 | boolean | true |
| cancel-text | 取消按钮文案 | string | '取消' |
| show-confirm | 是否显示确定按钮 | boolean | true |
| confirm-text | 确定按钮文案 | string | '确定' |
| overlay-closable | 点击遮罩是否关闭 | boolean | true |
| before-close | 关闭前的回调,返回 false 或 Promise{<rejected>} 可阻止关闭 | DialogBeforeClose | - |
| confirm-props | 设置确定按钮 props | ButtonProps | - |
| cancel-props | 设置取消按钮 props | ButtonProps | - |
DialogBeforeClose
- 当点击确定按钮时,
type为confirm; - 当点击取消按钮时,
type为cancel; - 当点击关闭按钮或遮罩时,
type为close。
loading 表示当前哪个按钮处于异步关闭状态。
ts
type DialogBeforeClose = (
type: 'close' | 'cancel' | 'confirm',
loading: {
readonly cancel: boolean
readonly confirm: boolean
readonly close: boolean
},
) => anyDialogSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义默认内容 | - |
DialogEmits
继承 MotionEmits。
| 事件 | 描述 | 类型 |
|---|---|---|
| update:visible | 对话框显隐时触发 | (visible: boolean) => void |
| close | 点击关闭按钮或遮罩时触发 | () => void |
| cancel | 点击取消按钮时触发 | () => void |
| confirm | 点击确定按钮时触发 | () => void |
命令式方法
| 名称 | 描述 | 类型 |
|---|---|---|
| dialog | 显示对话框 | DialogFunction |
| dialog.alert | 显示警告框 | DialogSimpleShowFunction |
| dialog.confirm | 显示确认框 | DialogSimpleShowFunction |
| dialog.hide | 隐藏命令式对话框 | () => void |
DialogFunction
ts
type DialogFunction = DialogSimpleShowFunction & {
alert: DialogSimpleShowFunction
confirm: DialogSimpleShowFunction
hide: () => void
}DialogSimpleShowFunction
ts
interface DialogSimpleShowFunction {
(options: DialogOptions): void
(title: string, options?: DialogOptions): void
}defaultDialogOptions
命令式默认值和声明式有所区别。
ts
const defaultDialogOptions = {
headed: false,
buttonType: 'text',
showCancel: false,
}主题定制
样式变量
| CSS 变量 | 值 |
|---|---|
--s-dialog-width | 320px |
--s-dialog-max-width | 90% |
--s-dialog-border-color | var(--s-border-color) |
--s-dialog-bg | var(--s-bg-color-elevated) |
--s-dialog-border-radius | var(--s-border-radius-xl) |
--s-dialog-header-padding-y | var(--s-size) |
--s-dialog-header-padding-x | var(--s-size) |
--s-dialog-body-padding-x | var(--s-size) |
--s-dialog-body-padding-y | var(--s-size-xl) |
--s-dialog-body-gap | var(--s-size-xs) |
--s-dialog-title-font-size | var(--s-font-size-lg) |
--s-dialog-title-headed-font-size | var(--s-font-size) |
--s-dialog-close-font-size | var(--s-font-size-lg) |
--s-dialog-message-font-size | var(--s-font-size) |
--s-dialog-message-color | var(--s-text-color-secondary) |
--s-dialog-footer-round-padding-x | var(--s-size) |
--s-dialog-footer-round-padding-y | var(--s-size) |
--s-dialog-footer-round-gap | var(--s-size) |