Teleport 的核心是 patch 阶段绕过默认挂载流程,定向插入目标容器;其 VNode 被标记为特殊类型,由 Teleport.process 处理,支持动态目标查找、DOM 迁移及上下文隔离。

渲染器处理 Teleport 组件的核心,是**在 patch 阶段绕过默认挂载流程,改为定向插入目标容器**。它不修改组件逻辑、不重建响应式上下文,只干预 DOM 节点的物理归属位置。
Teleport 的 VNode 类型被特殊标记
Vue 编译时,<Teleport> 会被生成为一个类型为 Teleport 的特殊 VNode(即 { type: Teleport, props, children, target, disabled }),而非普通元素或组件节点。渲染器在 patch 过程中遇到该类型,会立即识别并交由 Teleport.process 处理,而不是走常规的 patchElement 或 patchComponent 流程。
patch 阶段重定向 DOM 插入目标
当渲染器调用 process(n1, n2, container, anchor, internals) 时:
- 若为首次挂载(
n1 === null),则根据n2.props.to查找目标容器(如document.querySelector('body')),再对每个子节点patch(null, child, target, null),直接挂载到目标处 - 若发生更新,先正常比对子节点(
patchChildren),再判断to是否变更:若变更,则调用move(vnode, newTarget, null)将已挂载的真实 DOM 节点迁移过去 -
move函数内部区分组件实例(vnode.component.subTree.el)和普通元素(vnode.el),确保正确提取真实 DOM 引用
目标容器存在性与更新时机保障
Teleport 不会主动创建目标容器,仅依赖已有 DOM 节点:
- 若
to指向的选择器无匹配节点,且未启用disabled,内容将不会渲染(控制台警告) - 动态创建的目标容器(如 JS 新增的
<div id="modal-root"></div>)需确保在 Teleport 第一次patch前已插入文档,否则挂载失败 - 移动操作通过
queuePostFlushCb延迟到 nextTick 后执行,避免因目标容器尚未 ready 导致 DOM 操作报错
保持逻辑完整性与样式隔离
尽管 DOM 物理位置跨出组件树,但以下机制确保行为一致:
- 子组件仍运行在原始父组件的
setup()上下文、provide/inject链、响应式作用域中 - 事件监听绑定在真实 DOM 元素上,冒泡路径不受影响;
@click等仍可正常触发 -
<style scoped>作用域 CSS 仍基于源组件文件编译,与挂载位置无关 - SSR 中 Teleport 内容默认被跳过,需手动注入
__teleport字段配合服务端逻辑处理

















