teleport 本身不处理 promise,但为全局确认框的 promise 封装提供 dom 隔离基础;真正实现“调用即返回 promise”依赖组合逻辑、状态管理与异步通信机制,其中 teleport 确保 dialog 渲染位置正确、样式不受干扰且响应式上下文完整。

Vue 3 的 Teleport 本身不处理 Promise,但它为全局确认框(Dialog)的 Promise 封装提供了关键的 DOM 隔离基础。真正实现「调用即返回 Promise」的能力,靠的是组合逻辑 + 状态管理 + 异步通信机制,而 Teleport 负责确保这个 Dialog 渲染在合适位置、不被样式干扰、且保持响应式上下文完整。
✅ 核心思路:把 Dialog 组件变成一个可 await 的函数
不是在模板里写 <teleport><dialog></dialog></teleport>,而是封装成类似这样的调用:
const result = await showDialog({
title: '确认删除',
message: '该操作不可撤销,确定要继续吗?'
});
// result 是 { confirmed: true } 或 { confirmed: false }
```
? 实现三要素:Teleport + 全局状态 + Promise 控制器
-
Teleport 负责“渲染归位”:将 Dialog 挂载到
或专用容器(如#teleport-dialog-root),避免父级 overflow/z-index 干扰,保证视觉层级和交互可靠性 -
全局状态负责“统一入口”:用
provide/inject或 Pinia store 管理 Dialog 的显示开关、参数、回调 resolve/reject 函数 -
Promise 控制器负责“异步桥接”:每次调用
showDialog()时,内部创建一个Promise,并将它的resolve存入状态;Dialog 组件内点击「确认」或「取消」时,触发对应 resolve,Promise 即刻结束
? 关键细节:如何让 Teleport 不破坏 Promise 链
- Dialog 组件必须能访问外部传入的参数(通过 props 或 inject),同时能 emit 确认/取消事件 —— Teleport 不影响这些通信能力
- v-if 必须放在 Teleport 内部的根元素上(例如
<div class="dialog-wrapper" v-if="visible">),否则组件实例未销毁,下一次调用可能复用旧状态<li>不要在 Teleport 外层做 v-if 控制,否则 Promise resolve 后组件仍残留,且无法触发 unmounted 生命周期</li> <li>如果使用 transition,<code><transition></transition>必须包裹在 Teleport 内部,且与 v-if 同级,否则动画不会随 Promise 完成同步收起 - 支持多层弹窗时,用 zIndex 计数器动态分配层级,避免后开的 Dialog 被先开的遮挡
- 加超时兜底:Promise 可设 10s 自动 reject,防止用户关闭页面或意外失焦导致 pending
- 提供快捷方法:如
showConfirm()、showAlert(),底层复用同一套 Promise 机制,仅配置不同 UI 类型 - 错误场景保护:若调用时无挂载容器(如 #teleport-dialog-root 不存在),自动 fallback 到 console.warn + 同步返回 false,不阻断业务流程











