Skip to content
On this page

confirm 二次确认框

Hidden Title

基础用法:await confirm('确定删除当前记录吗?')

基础用法

成华主题

chenghua主题示例

石景山主题

shijingshan主题示例

在弹框中使用

测试

说明

confirm 用于在执行删除、提交、关闭等危险或重要操作前发起二次确认。它基于 Element Plus ElMessageBox.confirm 封装,默认补齐标题、按钮文案、按钮样式,并额外处理嵌套弹窗中的挂载节点和 Vue appContext

应用入口可通过 configureUtils({ theme: 'shijingshan' }) 设置全局默认主题。单次调用的 theme 会覆盖全局配置。

调用形式

ts
confirm(message)
confirm(message, options)
confirm(message, options, appContext)
confirm(options)
confirm(options, appContext)
confirm(message)
confirm(message, options)
confirm(message, options, appContext)
confirm(options)
confirm(options, appContext)

参数说明

参数类型必填默认值说明
messagestring | VNode | () => VNode-确认框内容。对象式调用时可通过 options.message 传入。
optionsConfirmOptions{}Element Plus ElMessageBoxOptions 配置,并额外支持 varianttargetappendToappContext
appContextAppContext | nullnullVue 应用上下文。多应用或需要渲染组件内容时可手动传入。

ConfirmOptions 常用字段:

字段类型默认值说明
titlestring'提示'确认框标题。
theme'default' | 'chenghua' | 'shijingshan'全局主题或 default确认框主题,设置为 'chenghua''shijingshan' 时使用对应主题样式。
variant'default' | 'delete' | 'warning'default语义样式;无须设置主题,也会同步容器、标题栏、正文和操作按钮样式。
targetstring | number-delete 场景的操作目标;message 为空时自动生成标准删除提示。
showCancelButtonbooleantrue是否显示取消按钮。
showClosebooleanElement Plus 默认值是否显示右上角关闭按钮。
closeOnClickModalbooleanElement Plus 默认值是否允许点击遮罩关闭。
closeOnPressEscapebooleanElement Plus 默认值是否允许按 Esc 关闭。
cancelButtonTextstring'取消'取消按钮文案。
confirmButtonTextstring'确定'确认按钮文案。
confirmButtonClassstring-确认按钮 class,可配合成华主题颜色类使用。
cancelButtonClassstring-取消按钮 class,可配合成华主题颜色类使用。
dangerouslyUseHTMLStringbooleantrue是否把字符串内容按 HTML 渲染。
appendTostring | HTMLElement | null自动识别当前弹窗指定 MessageBox 挂载节点。传普通字符串时会优先按 id 查询。
appContextAppContext | null自动解析手动指定 Vue 应用上下文。优先级高于第三个参数。

返回值

返回 ElMessageBox.confirmPromise。用户点击确认时 resolve;点击取消或关闭时 reject。

公共语义解析

confirm()s-dialogs-popconfirm 内部统一使用 resolveConfirmSemantic()。业务需要在自定义确认界面中复用相同规则时,也可以直接调用:

ts
import { resolveConfirmSemantic } from '@sybz-components/utils'

const semantic = resolveConfirmSemantic({
  variant: 'delete',
  target: '机器之心公众号',
  theme: 'shijingshan',
})
import { resolveConfirmSemantic } from '@sybz-components/utils'

const semantic = resolveConfirmSemantic({
  variant: 'delete',
  target: '机器之心公众号',
  theme: 'shijingshan',
})

返回结果包含 titleconfirmButtonTextconfirmButtonTypedefaultMessageclassNames 和目标状态。显式传入的标题及确认按钮配置优先于语义默认值。

常用场景

ts
await confirm('确定删除当前记录吗?')

await confirm({
  variant: 'delete',
  target: '机器之心公众号',
  theme: 'shijingshan',
})

await confirm('该操作可能影响现有数据,请确认后继续。', {
  variant: 'warning',
  theme: 'shijingshan',
})

await confirm('确认提交?', {
  confirmButtonText: '提交',
  cancelButtonText: '再想想',
})

await confirm('只提示确认按钮', {
  showCancelButton: false,
})

await confirm('当前内容存在未保存修改,建议返回检查后再离开。', {
  title: '离开提醒',
  theme: 'chenghua',
  showConfirmButton: false,
  cancelButtonText: '返回检查',
})

await confirm(
  '确定删除文件 <span class="s-confirm-file-name">成华AI服务申请表.xlsx</span> 吗?<br />删除后无法恢复。',
  {
    title: '删除确认',
    theme: 'chenghua',
    confirmButtonText: '确认删除',
    cancelButtonText: '再想想',
  },
)

await confirm('当前申请已提交,请等待平台审核。', {
  title: '提交成功',
  theme: 'chenghua',
  showCancelButton: false,
  confirmButtonText: '知道了',
})

await confirm('该操作需要通过底部按钮明确选择。', {
  title: '隐藏关闭按钮',
  theme: 'chenghua',
  showClose: false,
  closeOnClickModal: false,
  closeOnPressEscape: false,
  confirmButtonText: '继续处理',
  cancelButtonText: '暂不处理',
})

await confirm('请选择当前审批结果。', {
  title: '审批处理',
  theme: 'chenghua',
  confirmButtonText: '同意',
  cancelButtonText: '驳回',
  confirmButtonClass: 's-confirm-success-button',
  cancelButtonClass: 's-confirm-warning-button',
})

await confirm('第一行<br><span class="cl-blue">重点内容</span>', {
  dangerouslyUseHTMLString: true,
})
await confirm('确定删除当前记录吗?')

await confirm({
  variant: 'delete',
  target: '机器之心公众号',
  theme: 'shijingshan',
})

await confirm('该操作可能影响现有数据,请确认后继续。', {
  variant: 'warning',
  theme: 'shijingshan',
})

await confirm('确认提交?', {
  confirmButtonText: '提交',
  cancelButtonText: '再想想',
})

await confirm('只提示确认按钮', {
  showCancelButton: false,
})

await confirm('当前内容存在未保存修改,建议返回检查后再离开。', {
  title: '离开提醒',
  theme: 'chenghua',
  showConfirmButton: false,
  cancelButtonText: '返回检查',
})

await confirm(
  '确定删除文件 <span class="s-confirm-file-name">成华AI服务申请表.xlsx</span> 吗?<br />删除后无法恢复。',
  {
    title: '删除确认',
    theme: 'chenghua',
    confirmButtonText: '确认删除',
    cancelButtonText: '再想想',
  },
)

await confirm('当前申请已提交,请等待平台审核。', {
  title: '提交成功',
  theme: 'chenghua',
  showCancelButton: false,
  confirmButtonText: '知道了',
})

await confirm('该操作需要通过底部按钮明确选择。', {
  title: '隐藏关闭按钮',
  theme: 'chenghua',
  showClose: false,
  closeOnClickModal: false,
  closeOnPressEscape: false,
  confirmButtonText: '继续处理',
  cancelButtonText: '暂不处理',
})

await confirm('请选择当前审批结果。', {
  title: '审批处理',
  theme: 'chenghua',
  confirmButtonText: '同意',
  cancelButtonText: '驳回',
  confirmButtonClass: 's-confirm-success-button',
  cancelButtonClass: 's-confirm-warning-button',
})

await confirm('第一行<br><span class="cl-blue">重点内容</span>', {
  dangerouslyUseHTMLString: true,
})

注意事项

confirm 依赖 Element Plus 的 ElMessageBox,需要在浏览器端使用。默认开启 dangerouslyUseHTMLString,传入来自用户输入的 HTML 前要先做好可信处理,避免注入风险。嵌套 s-dialogel-dialog 中使用时,如果默认挂载位置不符合预期,可以显式传 appendTo

函数源码

confirm

来源:packages/utils/src/base.ts

/**
 * 打开确认框。
 *
 * 相比直接调用 `ElMessageBox.confirm`,这里额外处理了默认参数、嵌套弹窗挂载点和 `appContext`。
 *
 * @param message 确认框内容,支持字符串、VNode 或渲染函数。
 * @param options MessageBox 配置项。
 * @param appContext 可选的 Vue 应用上下文。
 * @returns `ElMessageBox.confirm` 返回的 Promise。
 *
 * @example
 * await confirm('确定删除吗?')
 *
 * @example
 * await confirm('确认提交?', {
 *   showCancelButton: true,
 *   appendTo: '#dialogRoot',
 * })
 *
 * @example
 * await confirm({
 *   variant: 'delete',
 *   target: '机器之心公众号',
 *   theme: 'shijingshan',
 * })
 */
export function confirm(
  options: ConfirmOptions,
  appContext?: AppContext | null,
): ReturnType<typeof ElMessageBox.confirm>
export function confirm(
  message: ConfirmMessage,
  options?: ConfirmOptions,
  appContext?: AppContext | null,
): ReturnType<typeof ElMessageBox.confirm>
export function confirm(
  messageOrOptions: ConfirmMessage | ConfirmOptions,
  optionsOrAppContext: ConfirmOptions | AppContext | null = null,
  appContext: AppContext | null = null,
) {
  const isOptionsCall = typeof messageOrOptions === 'object' && messageOrOptions !== null && !isVNode(messageOrOptions)
  const options = (isOptionsCall ? messageOrOptions : (optionsOrAppContext ?? {})) as ConfirmOptions
  const message = isOptionsCall ? (options.message ?? '') : (messageOrOptions as ConfirmMessage)
  const argumentAppContext = isOptionsCall ? (optionsOrAppContext as AppContext | null) : appContext
  const {
    message: _message,
    theme = utilsConfig.theme,
    variant = 'default',
    target,
    customClass,
    confirmButtonClass,
    cancelButtonClass,
    appendTo,
    appContext: optionAppContext,
    ...messageBoxOptions
  } = options
  const inputMessage = typeof message === 'function' ? message() : message
  const semantic = resolveConfirmSemantic({
    variant,
    target,
    theme,
    title: typeof messageBoxOptions.title === 'string' ? messageBoxOptions.title : undefined,
    confirmButtonText: messageBoxOptions.confirmButtonText,
  })
  const resolvedMessage =
    variant === 'delete' && semantic.hasTarget && !inputMessage
      ? `确认要删除<code type="danger">${_escapeHtml(semantic.target!)}</code>吗?删除后不可恢复。`
      : variant === 'delete' && !inputMessage
        ? semantic.defaultMessage
        : inputMessage
  const resolvedAppendTo = _resolveAppendTarget(appendTo)
  const resolvedAppContext = _resolveAppContext(optionAppContext || argumentAppContext)
  const isChenghuaTheme = theme === 'chenghua'
  const isShijingshanTheme = theme === 'shijingshan'
  const isSybzTheme = theme === 'sybz'

  const mergeOptions = {
    title: semantic.title,
    draggable: true,
    showCancelButton: true,
    cancelButtonText: '取消',
    confirmButtonText: semantic.confirmButtonText,
    dangerouslyUseHTMLString: true,
    ...messageBoxOptions,
    appendTo: resolvedAppendTo,
    appContext: resolvedAppContext,
    customClass: _mergeClassNames(
      isChenghuaTheme && CHENGHUA_CONFIRM_BOX_CLASS,
      isShijingshanTheme && SHIJINGSHAN_CONFIRM_BOX_CLASS,
      isSybzTheme && SYBZ_CONFIRM_BOX_CLASS,
      variant !== 'default' && `s-message-box--${variant}`,
      customClass,
    ),
    confirmButtonClass: _mergeClassNames(
      DEFAULT_CONFIRM_BUTTON_CLASS,
      isChenghuaTheme && CHENGHUA_CONFIRM_BUTTON_CLASS,
      isShijingshanTheme && SHIJINGSHAN_CONFIRM_BUTTON_CLASS,
      isSybzTheme && SYBZ_CONFIRM_BUTTON_CLASS,
      confirmButtonClass,
    ),
    cancelButtonClass: _mergeClassNames(
      DEFAULT_CANCEL_BUTTON_CLASS,
      isChenghuaTheme && CHENGHUA_CANCEL_BUTTON_CLASS,
      isShijingshanTheme && SHIJINGSHAN_CANCEL_BUTTON_CLASS,
      isSybzTheme && SYBZ_CANCEL_BUTTON_CLASS,
      cancelButtonClass,
    ),
  }

  return ElMessageBox.confirm(resolvedMessage, mergeOptions)
}

思云博智私有前端组件库