popconfirm —— 氣泡確認框
Esta página aún no está disponible en tu idioma.
刪除、提交、發布——這類「做了就難撤銷」的操作需要使用者再確認一次。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 FengMo WenXue