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 | 是否显示气泡,未传时使用内部状态 | boolean | undefined |
defaultVisible | 默认是否显示气泡,非受控模式使用 | boolean | false |
disabled | 是否禁用 | boolean | false |
width | 气泡宽度 | string | number | 150 |
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 | 确认按钮是否为 loading | boolean | false |
okButtonProps | 确认按钮 props | ButtonProps | - |
cancelButtonProps | 取消按钮 props | ButtonProps | - |
onBeforeOk | 确认前拦截,返回 false 阻止关闭;返回 Promise 时确认按钮进入 loading | (event: Event) => boolean | void | Promise<boolean | void> | - |
onBeforeCancel | 取消前拦截,返回 false 阻止关闭;返回 Promise 时取消按钮进入 loading | (event: Event) => boolean | void | Promise<boolean | void> | - |
renderTo | 弹层挂载容器 | string | HTMLElement | document.body |
renderToBody | 是否挂载到容器;关闭后可配合 Trigger 逻辑控制 Teleport | boolean | true |
unmountOnClose | 关闭时是否卸载弹层节点 | boolean | true |
popupClass | 弹层自定义类名 | string | - |
contentClass | 弹层内容自定义类名 | string | array | object | - |
contentStyle | 弹层内容自定义样式 | CSSProperties | - |
arrowClass | 箭头自定义类名 | string | array | object | - |
arrowStyle | 箭头自定义样式 | CSSProperties | - |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
update:modelValue | 显隐状态变化时触发,用于 v-model | value: boolean |
change | 显隐状态变化时触发 | value: boolean |
ok | 点击确认且未被拦截时触发 | event: Event |
cancel | 点击取消且未被拦截时触发 | event: Event |
Slots
| 插槽名 | 说明 |
|---|---|
default | 触发元素 |
content | 自定义确认内容 |
icon | 自定义默认内容布局中的图标 |
已知限制
- Popconfirm 现在基于
Trigger实现,滚动更新、外部点击关闭和箭头定位遵循 Trigger 当前行为。 - Esc 关闭目前在焦点位于弹层内时生效,触发元素仍依赖原生按钮键盘行为。