Skip to content

MessageBox 消息弹出框

模拟系统的消息弹出框而实现的一套模态对话框组件, 用于消息提示、消息确认和提交内容。

TIP

从设计上来说, MessageBox 的作用是美化系统自带的 alertconfirmprompt 方法, 因此适合展示较为简单的内容。如果需要弹出较为复杂的内容, 请使用 Dialog 组件。

消息提示

当用户进行操作时会被触发, 该对话框中断用户操作, 直到用户确认知晓后才可关闭。

调用 PxMessageBox.alert 方法以打开 alert 框。它模拟了系统的 alert, 无法通过按下 ESC 或点击框外关闭。此例中接收两个参数, messagetitle。值得一提的是, 窗口被关闭后, 它默认会返回一个 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 被赋值且被赋值为一个回调函数时, 在消息弹框被关闭之前将会被调用, 并且可以通过该方法来阻止弹框被关闭。它是一个接收三个参数:actioninstancedone 的方法。使用它能够在关闭前对实例进行一些操作, 比如为确定按钮添加 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 来开启拖拽弹窗能力。设置 overflowtrue 可以让拖拽范围超出可视区。

<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:

ts
import { PxMessageBox } from '@mmt817/pixel-ui'

那么对应于上述四个全局方法的调用方法依次为:PxMessageBoxPxMessageBox.alertPxMessageBox.confirmPxMessageBox.prompt, 参数同上所述。

API_Table插件测试

DANGER

该插件基于 markdown-it 开发, 解析组件 types.ts 文件生成 API 表格, 测试中

MessageBox API

Props

NameDescriptionTypeDefault
titleMessageBox 标题string-
messageMessageBox 正文内容string | VNode | (() => VNode)-
typeMessageBox 类型, 用于图标显示enum-
boxTypeMessageBox 类型enumalert
icon自定义图标string-
callback若不使用 Promise, 可以使用此参数指定 MessageBox 关闭后的回调functionnull
showClose是否显示关闭按钮booleantrue
beforeCloseMessageBox 关闭前的回调, 会暂停消息弹出框的关闭过程functionnull
lockScroll是否在 MessageBox 弹出后锁定背景滚动booleantrue
showCancelButton是否显示取消按钮booleanfalse
showConfirmButton是否显示确认按钮booleantrue
cancelButtonText取消按钮的文本内容string取消
confirmButtonText确认按钮的文本内容string确定
cancelButtonLoading是否显示取消按钮的加载状态booleanfalse
confirmButtonLoading是否显示确认按钮的加载状态booleanfalse
cancelButtonDisabled是否禁用取消按钮booleanfalse
confirmButtonDisabled是否禁用确认按钮booleanfalse
cancelButtonType取消按钮类型enum-
confirmButtonType确认按钮类型enumprimary
buttonSize自定义确认按钮及取消按钮的大小enumdefault
roundButton是否使用圆角按钮booleanfalse
showInput是否显示输入框booleanfalse
inputPlaceholder输入框占位文本string-
inputValue输入框初始值string-
inputType输入框类型stringtext
center是否居中布局booleanfalse
closeOnClickModal是否可通过点击遮罩层关闭 MessageBoxbooleantrue
draggable是否可拖拽booleanfalse
overflow拖动范围是否可超出可视区域(非容器区域)booleanfalse
overlayOptions继承自遮罩层属性, 详细参见 Overlay 组件overlayprops-
本站访客数 人次 本站总访问量