useMessageBox
命令式弹出 alert 与 confirm 对话框,以 Promise 形式获取用户的确认结果。
简介
useMessageBox 提供命令式弹窗 API,无需在模板中声明组件即可弹出对话框。它基于 MessageBox 组件与 Nuxt UI 的 useOverlay 实现。
const { alert, confirm } = useMessageBox()
两个方法的入参均为 MessageBox 的 props(mode 由方法自动设置):title、description、type、icon、按钮配置等,详见组件文档。
alert
alert(options) 弹出仅含确认动作的提示框,返回 Promise,用户关闭后才 resolve,适合阻塞式提示:
const { alert } = useMessageBox()
async function onSave() {
await save()
await alert({ type: 'success', title: '保存成功' })
// 用户关闭弹窗后继续
}
alert() 返回 Promise;用户关闭弹窗后才会 resolve,可用于强同步的提示流程。
[]
<script setup lang="ts">
import type { SemanticColor } from '@movk/nuxt'
const props = defineProps<{
type: SemanticColor
}>()
const { alert } = useMessageBox()
const log = ref<string[]>([])
async function showAlert() {
await alert({
type: props.type,
title: `${props.type} alert`,
description: '弹窗只暴露确认动作,关闭后 Promise 才会 resolve'
})
log.value = [`[${new Date().toLocaleTimeString()}] alert(${props.type}) closed`, ...log.value].slice(0, 6)
}
</script>
<template>
<div class="flex flex-col gap-3">
<UButton :color="type" variant="soft" size="sm" @click="showAlert">
alert · {{ type }}
</UButton>
<p class="text-xs text-muted">
<code>alert()</code> 返回 Promise;用户关闭弹窗后才会 resolve,可用于强同步的提示流程。
</p>
<pre class="text-xs bg-elevated/30 rounded p-3 overflow-auto max-h-40">{{ log }}</pre>
</div>
</template>
confirm
confirm(options) 返回 Promise<boolean>,把确认/取消映射为布尔值:
const { confirm } = useMessageBox()
async function onDelete() {
const ok = await confirm({
type: 'warning',
title: '删除确认',
description: '该操作不可恢复,确定继续?'
})
if (!ok) return
await remove()
}
confirm() 将确认或取消映射为 boolean 返回给调用方。
[]
<script setup lang="ts">
import type { SemanticColor } from '@movk/nuxt'
const props = defineProps<{
type: SemanticColor
}>()
const { confirm } = useMessageBox()
const log = ref<string[]>([])
async function showConfirm() {
const ok = await confirm({
type: props.type,
title: `${props.type} confirm`,
description: '弹窗返回确认结果,日志会记录 true / false'
})
log.value = [`[${new Date().toLocaleTimeString()}] confirm(${props.type}) → ${ok}`, ...log.value].slice(0, 6)
}
</script>
<template>
<div class="flex flex-col gap-3">
<UButton :color="type" variant="outline" size="sm" @click="showConfirm">
confirm · {{ type }}
</UButton>
<p class="text-xs text-muted">
<code>confirm()</code> 将确认或取消映射为 <code>boolean</code> 返回给调用方。
</p>
<pre class="text-xs bg-elevated/30 rounded p-3 overflow-auto max-h-40">{{ log }}</pre>
</div>
</template>
异步确认流程
confirm 适合串联异步流程——确认后再执行耗时任务:
等待 confirm() 结果后再串行执行后续请求;命令式 API 让流程在脚本里线性表达。
[]
<script setup lang="ts">
const { confirm } = useMessageBox()
const log = ref<string[]>([])
const pending = ref(false)
async function showAsync() {
const ok = await confirm({
type: 'warning',
title: '异步操作',
description: '确认后再执行模拟耗时任务,日志在流程完成时更新',
confirmButton: { label: '提交' }
})
if (!ok) {
log.value = [`[${new Date().toLocaleTimeString()}] 已取消`, ...log.value].slice(0, 6)
return
}
pending.value = true
await new Promise(r => setTimeout(r, 1500))
pending.value = false
log.value = [`[${new Date().toLocaleTimeString()}] async confirm 完成`, ...log.value].slice(0, 6)
}
</script>
<template>
<div class="flex flex-col gap-3">
<UButton color="warning" icon="i-lucide-zap" :loading="pending" @click="showAsync">
运行异步流程
</UButton>
<p class="text-xs text-muted">
等待 <code>confirm()</code> 结果后再串行执行后续请求;命令式 API 让流程在脚本里线性表达。
</p>
<pre class="text-xs bg-elevated/30 rounded p-3 overflow-auto max-h-40">{{ log }}</pre>
</div>
</template>