popconfirm —— 气泡确认框
本頁內容尚未翻譯。
删除、提交、发布——这类「做了就难撤销」的操作需要用户再确认一次。dialog 太重(模态、抢焦点、遮罩),popconfirm 就地弹一个小气泡:一句话 + 两个按钮,确认完立刻消失。它是交互重量刚好卡在 tooltip 与 dialog 之间的组件。
- 各端实现
<LhPopconfirm>:删除行、撤销操作、清空数据、提交订单。 - 轻量、就地、可撤销余地小的二次确认。
- 不该用它:后果严重到需要用户全神贯注的(用
dialog——模态遮罩强制聚焦);只是提示信息(用tooltip/message);需要填写理由或勾选项的确认(用dialog带表单)。
import { LH_POPCONFIRM_TYPE_DEFAULT, LH_POPCONFIRM_PLACEMENT_DEFAULT, getPopconfirmIconName, getPopconfirmClass, getPopconfirmTriggerAria, getPopconfirmPopperAria, getDefaultDelay, canCloseOnEscape,} from '@lh-ui/share/core/popconfirm'import type { LhPopconfirmType, LhPopconfirmTrigger, LhPopconfirmState } from '@lh-ui/share/core/popconfirm'默认语气是 warning 而非 info:LH_POPCONFIRM_TYPE_DEFAULT = 'warning'——确认框出现基本都意味着「有风险」,默认就该是警示语气。info 留给纯告知性确认(「确定标记为已读?」),danger 留给不可逆操作(「删除后不可恢复」)。
三种语气、三个图标:info → info、warning → warning、danger → error(图标名用 error 而非 danger——图标库的命名是 error,这是跨命名的映射)。未知 type 回退 warning。
role="alertdialog" 而非 popover 的 "dialog":alertdialog 是 ARIA 里「需要用户立即响应的对话框」——读屏软件会优先播报(类似 alert 的打断性,但要求用户做选择)。这比 dialog 更贴合「等你拍板」的语义。
确认/取消的事件契约在 UI 层:core 只出类名、图标、aria 和延迟;onConfirm / onCancel 事件、按钮文案、loading 态都在 UI 层——因为它们涉及组件树通信(emit),core 不碰框架 API。
延迟跟随 popover:getDefaultDelay 的默认是 200/100,与 popover 一致——确认气泡同样允许 hover 触发,指针要能走进去。
| 函数 | 签名 | 返回 | 作用 |
|---|---|---|---|
getPopconfirmIconName |
(type: LhPopconfirmType) => string |
图标名 | 未知 type 回退 warning |
getPopconfirmClass |
(state: { type, placement, popperClass? }) => string[] |
类名 | 语气 + 方位 |
getPopconfirmTriggerAria |
(visible, popperId?) => LhAriaAttrs |
aria 包 | expanded/controls/haspopup |
getPopconfirmPopperAria |
(id?) => LhAriaAttrs |
aria 包 | role=alertdialog |
getDefaultDelay |
(showAfter?, hideAfter?) => { show, hide } |
延迟 | 默认 200 / 100 |
canCloseOnEscape |
(state: { disabled }) => boolean |
是否允许 | disabled 时拦截 |
常量:LH_POPCONFIRM_TYPE_DEFAULT = 'warning'、LH_POPCONFIRM_PLACEMENT_DEFAULT = 'top'。
export type LhPopconfirmType = 'info' | 'warning' | 'danger'export type LhPopconfirmTrigger = 'click' | 'hover' | 'focus' | 'manual'
export interface LhPopconfirmState { type?: LhPopconfirmType trigger?: LhPopconfirmTrigger placement?: LhPlacement visible?: boolean disabled?: boolean showIcon?: boolean // 默认 true}getPopconfirmPopperAria('pc-1')// { role: 'alertdialog', id: 'pc-1' }getPopconfirmTriggerAria(true, 'pc-1')// { 'aria-expanded': true, 'aria-controls': 'pc-1', 'aria-haspopup': 'true' }- alertdialog 的播报:读屏软件遇到 alertdialog 会立即播报其内容(aria-labelledby 或内部文本),用户不需要主动去读——这是它比 dialog 强制性更强的地方,符合「等你确认」的意图。
- 按钮要有明确文案:「确定 / 取消」优于「OK / NO」或图标按钮。
danger语气下确认按钮文案建议写清后果(「删除」而非「确定」)。 - 取消是安全方向:Enter 默认触发确认还是取消?常见做法是初始焦点落在取消按钮上(Tab 一回车就安全退出)——破坏性操作不要把焦点预设到确认键。这是 UI 层的决定,core 不管。
- Esc = 取消:
canCloseOnEscape允许时,Esc 应触发 onCancel 而非单纯关闭——语义上「关闭确认框」就是「不确认」。 - 图标 aria-hidden:语义图标(warning/error)已由文案传达,图标本身装饰化,避免读屏重复播报「警告」。
import { getPopconfirmIconName, getPopconfirmClass, LH_POPCONFIRM_TYPE_DEFAULT } from '@lh-ui/share/core/popconfirm'
getPopconfirmIconName('info') // 'info'getPopconfirmIconName('warning') // 'warning'getPopconfirmIconName('danger') // 'error'getPopconfirmIconName('other' as never) // 'warning'(兜底)
getPopconfirmClass({ type: 'danger', placement: 'top' })// ['lh-popconfirm__popper', 'lh-popconfirm__popper--danger', 'lh-popconfirm__popper--top']
LH_POPCONFIRM_TYPE_DEFAULT // 'warning'<!-- Vue3 --><template> <LhPopconfirm title="删除后不可恢复,确定删除该行?" type="danger" confirm-text="删除" cancel-text="取消" @confirm="remove(row)" > <template #reference> <LhButton type="danger" size="small">删除</LhButton> </template> </LhPopconfirm></template>
<script setup>async function remove(row) { // onConfirm 触发;组件内部可支持 confirmLoading:异步完成后才关闭气泡 await api.delete(row.id) LhMessage.success('已删除')}</script>// 异步确认:confirm 期间禁用按钮 + 显示 loading,失败时保持气泡打开// 这是 UI 层逻辑:core 不持有异步状态// React:onConfirm/onCancel 由 props 传入;受控 visible 配合异步确认// uniapp:<view> 气泡;按钮点击态用 hover-class;事件契约同模型| 类名 | 语义 |
|---|---|
.lh-popconfirm__popper |
气泡容器 |
.lh-popconfirm__popper--{info|warning|danger} |
语气(图标色 + 确认按钮色) |
.lh-popconfirm__popper--{top|bottom|…} |
方位 |
.lh-popconfirm__icon |
语气图标 |
.lh-popconfirm__title |
标题文案 |
.lh-popconfirm__actions |
按钮区(右对齐) |
确认按钮颜色随语气:danger 用 --lh-danger-color,warning 用 --lh-warning-color,info 用 --lh-primary-color。
- 标题写清后果:「确定删除吗?」是坏文案(没说后果);「删除后不可恢复,确定删除该行?」是好文案。这是 popconfirm 体验的核心。
- 不要嵌套:popconfirm 里再套 popconfirm 会让用户疑惑当前在确认哪一层。需要多步确认用 dialog。
- 触发器是禁用按钮时:
disabled的按钮不触发事件(原生限制),popconfirm 打不开——业务层要自行处理(包一层非禁用元素,或禁用时直接不渲染)。 - 异步确认的关闭时机:confirm 处理中应禁用两个按钮 + 遮罩防重复点击;失败时保持气泡打开并提示错误,成功才关闭。直接在 onConfirm 里同步关气泡是常见 bug。
- 与 message 的配合:确认完成后用
message给成功反馈(「已删除」),两者是「确认 → 执行 → 反馈」的标准链路。 - 移动端 hover 触发:同 popover,触屏无 hover。跨端默认用 click 触发。
role="alertdialog"不含按钮的隐式语义:按钮区要渲染成真正的<button>(不是 div + onclick),键盘用户才能操作。
@lh-ui/share/core/popconfirm → getPopconfirmIconName( )(填好参数后点运行)Copyright © 2024-2026 风默文学 | 宁ICP备2024006574号 |
苏公网安备32040002010537