MessageBox 消息弹出框
模拟系统的消息弹出框而实现的一套模态对话框组件, 用于消息提示、消息确认和提交内容。
TIP
从设计上来说, MessageBox 的作用是美化系统自带的 alert
、confirm
和 prompt
方法, 因此适合展示较为简单的内容。如果需要弹出较为复杂的内容, 请使用 Dialog 组件。
消息提示
当用户进行操作时会被触发, 该对话框中断用户操作, 直到用户确认知晓后才可关闭。
调用 PxMessageBox.alert
方法以打开 alert 框。它模拟了系统的 alert, 无法通过按下 ESC 或点击框外关闭。此例中接收两个参数, message
和title
。值得一提的是, 窗口被关闭后, 它默认会返回一个 Promise
对象便于进行后续操作的处理。若不确定浏览器是否支持 Promise
, 可自行引入第三方 polyfill
或像本例一样使用回调进行后续处理。
<template>
<px-button @click="open">Click to open the alert</px-button>
</template>
<script lang="ts" setup>
import {
PxMessage,
PxMessageBox,
type MessageBoxAction
} from '@mmt817/pixel-ui'
const open = () => {
PxMessageBox.alert('This is a message', 'Title', {
confirmButtonText: 'OK',
type: 'success',
callback: (
action: MessageBoxAction | { value: string; action: MessageBoxAction }
) => {
PxMessage({
type: 'info',
message: `action: ${action}`
})
}
})
}
</script>
确认消息
提示用户确认其已经触发的动作, 并询问是否进行此操作时会用到此对话框。
调用 PxMessageBox.confirm
方法以打开 confirm 框。它模拟了系统的 confirm, MessageBox 组件也拥有极高的定制性, 我们可以传入 options
作为第三个参数, 它是一个字面量对象。type
字段表明消息类型, 可指定消息外观及图标类型, 需要注意的是, 第二个参数 title
必须定义为 String
类型, 如果是 Object
, 则会被当做为 options
使用。在这里我们返回了一个 Promise
来处理后续响应。
<template>
<px-button @click="open">Click to open the Confirm</px-button>
</template>
<script lang="ts" setup>
import { PxMessage, PxMessageBox } from '@mmt817/pixel-ui'
const open = () => {
PxMessageBox.confirm(
'proxy will permanently delete the file. Continue?',
'Warning',
{
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning'
}
)
.then(() => {
PxMessage({
type: 'success',
message: 'Delete completed'
})
})
.catch(() => {
PxMessage({
type: 'info',
message: 'Delete canceled'
})
})
}
</script>
提交内容
当需要用户输入内容时, 可以使用 Prompt 类型的消息框。
调用 PxMessageBox.prompt
方法以打开 prompt 框。它模拟了系统的 prompt, 可通过 showInput
启用输入框, inputType
指定输入框类型, inputValue
数据绑定, inputPlaceholder
定义输入框的占位符。
<template>
<px-button @click="openConfirm"> Click to open the Prompt</px-button>
</template>
<script setup lang="ts">
import {
PxMessage,
PxMessageBox,
type MessageBoxAction
} from '@mmt817/pixel-ui'
function openConfirm() {
PxMessageBox.prompt('Place input your name', 'Tip', { type: 'info' })
.then(({ value }: any) => {
PxMessage.success(`your name is: ${value}`)
})
.catch((action: MessageBoxAction) => {
PxMessage.warning(`action: ${action}`)
})
}
</script>
使用 VNode
message
可以是一个 VNode, 允许你使用自定义的模板。
<template>
<px-button @click="open1">Common VNode</px-button>
<px-button @click="open2">Dynamic props</px-button>
</template>
<script setup lang="ts">
import { h } from 'vue'
import { PxMessageBox, PxTag } from '@mmt817/pixel-ui'
function open1() {
PxMessageBox({
title: 'Message',
message: h('p', null, [
h('span', null, 'Message can be '),
h('i', { style: 'color: teal' }, 'VNode')
])
})
}
function open2() {
PxMessageBox({
title: 'Message',
type: 'success',
message: () =>
h(
PxTag,
{
type: 'success',
closable: true
},
'VNode'
)
})
}
</script>
个性化
消息弹框可以被定制来展示各种内容。
上面提到的三个方法都是对 PxMessageBox
方法的二次包装。本例直接调用 PxMessageBox
方法, 使用 showCancelButton
字段, 用于显示取消按钮。另外可用 cancelButtonText
来自定义取消按钮文本 (Confirm 按钮也具有相同的字段, 在文末的 API 说明中有完整的字段列表)。
此例还使用了 beforeClose
属性, 当 beforeClose
被赋值且被赋值为一个回调函数时, 在消息弹框被关闭之前将会被调用, 并且可以通过该方法来阻止弹框被关闭。它是一个接收三个参数:action
、instance
和 done
的方法。使用它能够在关闭前对实例进行一些操作, 比如为确定按钮添加 loading
状态等; 此时若需要关闭实例, 可以调用 done
方法 (若在 beforeClose
中没有调用 done
, 则弹框便不会关闭)。
<template>
<px-button @click="openMsgBox">with callback</px-button>
</template>
<script setup lang="ts">
import { h } from 'vue'
import { delay } from 'lodash-es'
import { PxMessage, PxMessageBox } from '@mmt817/pixel-ui'
import type { MessageBoxAction, MessageBoxOptions } from '@mmt817/pixel-ui'
async function openMsgBox() {
try {
const action = await PxMessageBox({
title: 'Message',
message: h('p', null, [
h('span', null, 'Message can be '),
h('i', { style: 'color: teal' }, 'VNode')
]),
showCancelButton: true,
confirmButtonText: 'Yes',
cancelButtonText: 'No',
type: 'danger',
icon: 'trash',
beforeClose(
action: MessageBoxAction,
instance: MessageBoxOptions,
done: () => void
) {
if (action !== 'confirm') {
done()
return
}
instance.confirmButtonLoading = true
instance.confirmButtonText = 'Loading...'
delay(() => {
done()
delay(() => (instance.confirmButtonLoading = false), 1000)
}, 3000)
}
})
PxMessage.success(`action : ${action}`)
} catch (action) {
PxMessage.warning(`action : ${action}`)
}
}
</script>
区分取消操作与关闭操作
有些场景下, 点击取消按钮与点击关闭按钮有着不同的含义。
默认情况下, 当用户触发取消 (点击取消按钮) 和触发关闭 (点击关闭按钮或遮罩层、按下 ESC 键) 时, Promise 的 reject 回调和 callback
回调的参数分别为 'cancel' 和 'close'。
内容居中
消息弹框支持使用居中布局。
将 center
属性设置为 true
可将内容居中显示。
<template>
<px-button @click="openMsgBox">Content Center</px-button>
</template>
<script setup lang="ts">
import {
PxMessage,
PxMessageBox,
type MessageBoxAction
} from '@mmt817/pixel-ui'
function openMsgBox() {
PxMessageBox.confirm(
'proxy will permanently delete the file. Continue?',
'Warning',
{
type: 'warning',
center: true,
// 这里展示一下 不用 Promise 写法的时候
callback: (
action: MessageBoxAction | { value: string; action: MessageBoxAction }
) => {
if (action === 'confirm') {
PxMessage.success(action)
} else {
PxMessage.warning(action as string)
}
}
}
)
}
</script>
自定义图标
通过 icon
属性设置图标, 或使用任意 Vue 组件、渲染函数 (JSX) 来自定义。
<template>
<px-button @click="open">Custom Icon</px-button>
</template>
<script lang="ts" setup>
import { PxMessageBox } from '@mmt817/pixel-ui'
const open = () => {
PxMessageBox.confirm(
'It will permanently delete the file. Continue?',
'Warning',
{
type: 'danger',
icon: 'imgur',
center: true
}
)
}
</script>
拖拽 API
设置 MessageBox 可以拖拽。
设置 draggable
属性为 true
来开启拖拽弹窗能力。设置 overflow
为 true
可以让拖拽范围超出可视区。
<template>
<px-button @click="open">Open a draggable Box</px-button>
<px-button @click="open2"> Open a overflow draggable Box </px-button>
</template>
<script lang="ts" setup>
import { PxMessage, PxMessageBox } from '@mmt817/pixel-ui'
const open = () => {
PxMessageBox.confirm(
'proxy will permanently delete the file. Continue?',
'Warning',
{
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning',
draggable: true
}
)
.then(() => {
PxMessage({
type: 'success',
message: 'Delete completed'
})
})
.catch(() => {
PxMessage({
type: 'info',
message: 'Delete canceled'
})
})
}
const open2 = () => {
PxMessageBox.confirm(
'proxy will permanently delete the file. Continue?',
'Warning',
{
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning',
draggable: true,
overflow: true
}
)
.then(() => {
PxMessage({
type: 'success',
message: 'Delete completed'
})
})
.catch(() => {
PxMessage({
type: 'info',
message: 'Delete canceled'
})
})
}
</script>
定制化风格
特殊的, 组件库当前将 iron
, stamp
集成到 type
属性中, 可配置查看使用
同时, 继承 OverlayProps
属性, 可配置 Overlay 组件样式
<template>
<px-button @click="open1" class="iron-btn">Iron</px-button>
<px-button @click="open2" class="stamp-btn">Stamp</px-button>
</template>
<script lang="ts" setup>
import { PxMessageBox } from '@mmt817/pixel-ui'
const open1 = () => {
PxMessageBox.confirm(
'It will permanently delete the file. Continue?',
'Warning',
{
type: 'iron',
icon: 'imgur',
center: true,
matte: true,
preset1: true
}
)
}
const open2 = () => {
PxMessageBox.confirm(
'It will permanently delete the file. Continue?',
'Warning',
{
type: 'stamp',
icon: 'imgur',
center: true,
grid: true,
draggable: true
}
)
}
</script>
<style scoped>
.iron-btn {
--px-button-text-color: #8f9db5;
--px-border-color: #b4c0d2;
--px-bg-color: #3a4567;
--px-bg-shadow-color: #252d46;
&:hover {
--px-bg-color: #3a4567;
}
}
.stamp-btn {
--px-bg-color: #ebe6e0;
--px-bg-shadow-color: #00000033;
&:hover {
--px-bg-color: #ebe6e0;
}
}
</style>
全局方法
如果你完整引入了 PxielUI, 它会为 app.config.globalProperties
添加如下全局方法: $msgbox
、 $alert
、$confirm
和 $prompt
。 因此在 Vue 实例中可以采用本页面中的方式来调用 MessageBox。参数如下:
$msgbox(options)
$alert(message, title, options)
或$alert(message, options)
$confirm(message, title, options)
或$confirm(message, options)
$prompt(message, title, options)
或$prompt(message, options)
单独引用
如果您需要按需引入 MessageBox:
import { PxMessageBox } from '@mmt817/pixel-ui'
那么对应于上述四个全局方法的调用方法依次为:PxMessageBox
、PxMessageBox.alert
、PxMessageBox.confirm
和 PxMessageBox.prompt
, 参数同上所述。
API_Table插件测试
DANGER
该插件基于 markdown-it
开发, 解析组件 types.ts
文件生成 API 表格, 测试中
MessageBox API
Props
Name | Description | Type | Default |
---|---|---|---|
title | MessageBox 标题 | string | - |
message | MessageBox 正文内容 | string | VNode | (() => VNode) | - |
type | MessageBox 类型, 用于图标显示 | enum | - |
boxType | MessageBox 类型 | enum | alert |
icon | 自定义图标 | string | - |
callback | 若不使用 Promise, 可以使用此参数指定 MessageBox 关闭后的回调 | function | null |
showClose | 是否显示关闭按钮 | boolean | true |
beforeClose | MessageBox 关闭前的回调, 会暂停消息弹出框的关闭过程 | function | null |
lockScroll | 是否在 MessageBox 弹出后锁定背景滚动 | boolean | true |
showCancelButton | 是否显示取消按钮 | boolean | false |
showConfirmButton | 是否显示确认按钮 | boolean | true |
cancelButtonText | 取消按钮的文本内容 | string | 取消 |
confirmButtonText | 确认按钮的文本内容 | string | 确定 |
cancelButtonLoading | 是否显示取消按钮的加载状态 | boolean | false |
confirmButtonLoading | 是否显示确认按钮的加载状态 | boolean | false |
cancelButtonDisabled | 是否禁用取消按钮 | boolean | false |
confirmButtonDisabled | 是否禁用确认按钮 | boolean | false |
cancelButtonType | 取消按钮类型 | enum | - |
confirmButtonType | 确认按钮类型 | enum | primary |
buttonSize | 自定义确认按钮及取消按钮的大小 | enum | default |
roundButton | 是否使用圆角按钮 | boolean | false |
showInput | 是否显示输入框 | boolean | false |
inputPlaceholder | 输入框占位文本 | string | - |
inputValue | 输入框初始值 | string | - |
inputType | 输入框类型 | string | text |
center | 是否居中布局 | boolean | false |
closeOnClickModal | 是否可通过点击遮罩层关闭 MessageBox | boolean | true |
draggable | 是否可拖拽 | boolean | false |
overflow | 拖动范围是否可超出可视区域(非容器区域) | boolean | false |
overlayOptions | 继承自遮罩层属性, 详细参见 Overlay 组件 | overlayprops | - |