全局弹窗
将共享确认服务接入应用根组件,并区分 Confirm 与 Toast 的状态、并发和生命周期职责。
#howto
#evergreen
#component-patterns
[!info] related notes
- 模式选择:前端弹窗与确认框
- Vue/Vuetify 实现:ConfirmDialog 实现
- 状态排障:Vue 全局对话框状态不共享
全局弹窗
目标是让调用方与渲染 Provider 共享同一确认服务,而不是保证整个页面只有一个弹窗 DOM 节点。UI 库可能通过 Teleport/Portal 创建遮罩和内容节点。
接入步骤
- 在应用根层挂载确认 Provider;Toast 使用自己的 Toaster,不能替代确认 Provider。
- 业务组件和 Provider 使用同一服务实例。浏览器单应用可使用模块实例;SSR 按应用/请求创建并通过 provide/inject 等机制共享。
- 调用 confirm 后检查返回值,只有明确 true 才执行业务动作。
- 确认、取消、关闭与卸载统一结束请求并清理 resolver;并发策略必须明确。
共享状态与 Vuetify 组件的完整示例统一维护在 ConfirmDialog 实现,不在这里重复一套只能保存单个 resolver 却声称支持并发的实现。
Confirm 与 Toast
Confirm 等待用户决策;Toast 报告结果。toast.promise 可以展示异步任务进度,但不会阻塞任务等待用户批准,且具体 API 取决于安装的 Vue/React 库。
前端确认也不替代服务端权限、资源版本检查与幂等;用户确认后,请求仍可能失败或结果未知。
验证
- 从深层组件发起,Provider 能展示相同请求。
- 连续请求按约定拒绝或排队,不能丢失任一 Promise。
- false、关闭和卸载都不执行待确认动作;重复点击不会重复结束任务。
- 检查可访问名称、焦点进入与返回、键盘行为;不能以 DOM 节点数量判断正确性。