Skip to content

Popconfirm 气泡确认

用于在按钮或链接旁边完成低成本二次确认。

何时使用

  • 操作会产生删除、提交、发布等不可直接撤销的结果。
  • 不需要打断整页流程,只需要在触发元素附近让用户二次确认。
  • 确认内容较短,适合在小型气泡中展示。

基础用法

vue
<template>
  <x-popconfirm content="确认删除这条记录?" @ok="handleOk" @cancel="handleCancel">
    <x-button status="danger">删除</x-button>
  </x-popconfirm>
</template>

<script setup lang="ts">
const handleOk = (event: Event) => {
  console.log('ok', event);
};

const handleCancel = (event: Event) => {
  console.log('cancel', event);
};
</script>

类型

vue
<template>
  <x-space wrap>
    <x-popconfirm type="danger" content="危险操作确认?">
      <x-button status="danger">Danger</x-button>
    </x-popconfirm>
    <x-popconfirm type="warning" content="继续执行风险操作?">
      <x-button status="warning">Warning</x-button>
    </x-popconfirm>
    <x-popconfirm type="success" content="确认完成任务?">
      <x-button status="success">Success</x-button>
    </x-popconfirm>
  </x-space>
</template>

位置

vue
<template>
  <x-space wrap>
    <x-popconfirm position="top" content="上方弹出">
      <x-button>Top</x-button>
    </x-popconfirm>
    <x-popconfirm position="bottom" content="下方弹出">
      <x-button>Bottom</x-button>
    </x-popconfirm>
    <x-popconfirm position="left" content="左侧弹出">
      <x-button>Left</x-button>
    </x-popconfirm>
    <x-popconfirm position="right" content="右侧弹出">
      <x-button>Right</x-button>
    </x-popconfirm>
  </x-space>
</template>

受控显示

当前状态:隐藏
vue
<template>
  <x-space>
    <x-popconfirm v-model="visible" content="确认提交当前表单?" position="bottom">
      <x-button type="primary">提交</x-button>
    </x-popconfirm>
    <x-button @click="visible = true">外部打开</x-button>
    <x-button @click="visible = false">外部关闭</x-button>
  </x-space>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const visible = ref(false);
</script>

默认显示

vue
<template>
  <x-popconfirm default-visible content="默认打开,点击取消或确认会关闭">
    <x-button>默认打开</x-button>
  </x-popconfirm>
</template>

异步拦截

vue
<template>
  <x-popconfirm content="1 秒后完成确认" :on-before-ok="beforeOk" @ok="handleOk">
    <x-button type="primary">异步确认</x-button>
  </x-popconfirm>
</template>

<script setup lang="ts">
const beforeOk = () => {
  return new Promise<boolean>((resolve) => {
    window.setTimeout(() => resolve(true), 1000);
  });
};

const handleOk = () => {
  console.log('confirmed');
};
</script>

按钮状态

vue
<template>
  <x-space>
    <x-popconfirm
      v-model="visible"
      content="确认按钮 loading 可由外部状态控制"
      ok-text="保存"
      :ok-loading="saving"
      :ok-button-props="{ status: 'success' }"
      :cancel-button-props="{ type: 'text' }"
      @ok="handleOk"
    >
      <x-button>按钮 Props</x-button>
    </x-popconfirm>
    <x-button @click="saving = !saving">
      {{ saving ? '关闭 loading' : '开启 loading' }}
    </x-button>
  </x-space>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const visible = ref(false);
const saving = ref(false);

const handleOk = () => {
  visible.value = false;
};
</script>

自定义内容

vue
<template>
  <x-popconfirm width="240" ok-text="归档" cancel-text="取消">
    <x-button>归档项目</x-button>
    <template #icon>
      <span class="demo-popconfirm-icon">!</span>
    </template>
    <template #content>
      <div class="demo-popconfirm-content">
        <strong>归档后项目将移入历史列表</strong>
        <span>团队成员仍可在历史项目中查看。</span>
      </div>
    </template>
  </x-popconfirm>
</template>

禁用状态

vue
<template>
  <x-popconfirm disabled content="禁用后不会弹出">
    <x-button disabled>禁用触发</x-button>
  </x-popconfirm>
</template>

按需导入

ts
import { Popconfirm } from 'x-next';

Props

参数说明类型默认值
modelValue是否显示气泡,未传时使用内部状态booleanundefined
defaultVisible默认是否显示气泡,非受控模式使用booleanfalse
disabled是否禁用booleanfalse
width气泡宽度string | number150
type类型'primary' | 'success' | 'warning' | 'strong' | 'danger''danger'
content确认内容string | number-
position弹出位置'top' | 'tl' | 'tr' | 'bottom' | 'bl' | 'br' | 'left' | 'lt' | 'lb' | 'right' | 'rt' | 'rb''top'
okText确认按钮文案string'确认'
cancelText取消按钮文案string'取消'
okLoading确认按钮是否为 loadingbooleanfalse
okButtonProps确认按钮 propsButtonProps-
cancelButtonProps取消按钮 propsButtonProps-
onBeforeOk确认前拦截,返回 false 阻止关闭;返回 Promise 时确认按钮进入 loading(event: Event) => boolean | void | Promise<boolean | void>-
onBeforeCancel取消前拦截,返回 false 阻止关闭;返回 Promise 时取消按钮进入 loading(event: Event) => boolean | void | Promise<boolean | void>-
renderTo弹层挂载容器string | HTMLElementdocument.body
renderToBody是否挂载到容器;关闭后可配合 Trigger 逻辑控制 Teleportbooleantrue
unmountOnClose关闭时是否卸载弹层节点booleantrue
popupClass弹层自定义类名string-
contentClass弹层内容自定义类名string | array | object-
contentStyle弹层内容自定义样式CSSProperties-
arrowClass箭头自定义类名string | array | object-
arrowStyle箭头自定义样式CSSProperties-

Events

事件名说明回调参数
update:modelValue显隐状态变化时触发,用于 v-modelvalue: boolean
change显隐状态变化时触发value: boolean
ok点击确认且未被拦截时触发event: Event
cancel点击取消且未被拦截时触发event: Event

Slots

插槽名说明
default触发元素
content自定义确认内容
icon自定义默认内容布局中的图标

已知限制

  • Popconfirm 现在基于 Trigger 实现,滚动更新、外部点击关闭和箭头定位遵循 Trigger 当前行为。
  • Esc 关闭目前在焦点位于弹层内时生效,触发元素仍依赖原生按钮键盘行为。