Skip to content

Confirm 确认框

破坏性操作的二次确认。声明式与命令式两种用法。

声明式

vue
<script setup>
import { ref } from 'vue'
const visible = ref(false)
</script>

<template>
  <SrButton variant="danger" @click="visible = true">删除</SrButton>

  <SrConfirm
    v-model="visible"
    type="danger"
    title="删除确认"
    content="该操作不可撤销,确定继续?"
    confirm-text="删除"
    @confirm="handleDelete"
  />
</template>

命令式

srConfirm() 返回一个 Promisetrue 表示确认、false 表示取消。 调用处不需要维护 visible 状态,因此代码短得多。

vue
<script setup>
import { srConfirm } from '@starriver/ui'

async function handleDelete() {
  const ok = await srConfirm({
    type: 'danger',
    title: '删除确认',
    content: '该操作不可撤销,确定继续?',
    confirmText: '删除'
  })

  if (!ok) return

  await deleteItem()
}
</script>

什么时候该用命令式

判断标准是「这个确认框和哪个组件绑定」

场景推荐原因
确认框由某个按钮触发命令式不必为了它多维护一个 ref,逻辑也都在 handleDelete
确认框内容随状态频繁变化声明式命令式的参数只传一次,动态内容不好改
确认框需要在模板中定位(如自定义插槽)声明式命令式创建在独立的挂载点上

命令式最常见——「点删除 → 问一下 → 真删」这类逻辑, 用命令式写出来就是几行,用声明式则需要在组件里多一个 ref、 在模板里多一个 <SrConfirm>,而且两者相隔很远。

命令式的挂载点

它在第一次调用时创建并挂到一个独立容器上(与 toast 共用机制), 因此不需要在模板里放任何东西

SSR 环境下调用是安全的——会返回 false 而不抛错, 因为服务端渲染时用户不可能做出选择。

类型与文案

vue
<SrConfirm type="primary" confirm-text="确定" />
<SrConfirm type="warning" confirm-text="我确定" />
<SrConfirm type="danger" confirm-text="删除" danger />

type 决定图标与确定按钮的配色:

类型用途确定按钮文案建议
primary中性确认「确定」
warning有风险但可逆「继续」
danger不可逆操作动词——「删除」「清空」

危险操作的按钮文案要写动词

「确定」这个词在删除场景下很糟——用户读到的是"确定要做什么", 答"确定"很自然,结果数据没了。

把按钮写成「删除」,用户按下时至少知道自己在做什么。 这也是 confirm-text 存在的原因。

单按钮模式

show-cancel="false" 只显示确定按钮,用于纯粹的通知。

vue
<SrConfirm v-model="visible" :show-cancel="false" />

异步与加载态

loading 让确定按钮进入加载状态,避免重复点击。

vue
<script setup>
const visible = ref(false)
const submitting = ref(false)

async function onOk() {
  submitting.value = true
  try {
    await submit()
    visible.value = false
  } finally {
    submitting.value = false
  }
}
</script>

<template>
  <SrConfirm v-model="visible" :loading="submitting" @confirm="onOk" />
</template>

命令式如何配合异步

srConfirm() 在用户点确定后立即 resolve,不等你的异步操作完成。

需要"确定后加载、完成才关闭"的效果,用声明式更顺手—— 或者在 await 之后再用命令式开一个的结果提示。

Props

名称类型默认值说明
modelValuebooleanfalse是否显示
titlestring标题
contentstring正文
type'primary' | 'warning' | 'danger''primary'类型
confirmTextstring'确定'确定按钮文案
cancelTextstring'取消'取消按钮文案
showCancelbooleantrue是否显示取消按钮
loadingbooleanfalse确定按钮是否加载中
closeOnOverlaybooleanfalse点击遮罩是否关闭(默认

srConfirm(options)

接受上述 props 的子集,返回 Promise<boolean>

ts
const ok = await srConfirm({
  type: 'danger',
  title: '删除确认',
  content: '该操作不可撤销',
  confirmText: '删除',
  cancelText: '再想想'
})

事件

事件说明
confirm点击确定
cancel点击取消或关闭
update:modelValue显隐变化

无障碍

  • Modal 相同的四要素(Teleport、层级令牌、ESC 与焦点归还、滚动锁定)
  • 容器带 role="alertdialog"——这比 role="dialog" 更准确: 它告诉读屏软件内容需要立即处理,会先朗读全文再让用户操作
  • 初始焦点落在取消按钮上(危险操作时)——用户误按回车不会触发删除。 这是破坏性确认框的一个重要细节

自用组件库 · 源码分发 · 不发布 npm