Teleport 的核心作用是脱离当前 DOM 层级渲染,它不改变组件逻辑,仅在 patch 阶段将子组件 DOM 插入指定目标容器(如 document.body),解决模态框等需脱离布局流又需响应式的问题。

Teleport 的核心作用:脱离当前 DOM 层级渲染
Teleport 不改变组件逻辑,只改变挂载位置。 它让子组件的虚拟 DOM 节点在 patch 阶段被插入到指定目标容器(如 document.body),而非父组件的 DOM 子树中。这解决了模态框、通知浮层等需要脱离布局流又需响应式数据的问题。
虚拟 DOM 层面的关键处理:render 函数与 patch 分离
Vue3 中, 是一个内置组件,其 render 函数不直接返回子节点 VNode,而是返回一个特殊的 teleport 类型 VNode({ type: Teleport, children, target, disabled })。这个 VNode 会被 renderer 在 patch 阶段特殊处理:
- 正常递归 patch 时,遇到
TeleportVNode,renderer 暂停当前父容器的子节点挂载流程 - 提取
children(即内部内容)并生成对应真实 DOM 节点 - 根据
target(如querySelector('#modal'))找到目标容器,将生成的 DOM 直接appendChild或insertBefore - 若
target不存在或disabled为 true,则退化为普通挂载(保留在原位置)
响应式更新与事件委托的保障机制
Teleport 内部组件仍处于同一响应式上下文,setup()、ref、watch 等完全可用。事件绑定也正常——因为事件监听器仍注册在 Teleport 内部的真实 DOM 元素上,浏览器事件冒泡路径不受挂载位置影响。唯一要注意的是:
- CSS 样式作用域(如
)依然基于组件文件,与挂载位置无关 - 若目标容器非
body下静态节点(如动态创建的div),需确保target在 Teleport 执行 patch 前已存在,否则内容不会渲染 - 服务端渲染(SSR)中,Teleport 内容默认被忽略,需配合
__teleport注入逻辑做特殊处理
底层关键代码路径(简化示意)
实际运行中,核心逻辑位于 packages/runtime-core/src/components/Teleport.ts,主要入口是 process 函数:
-
process(n1, n2, container, ...):n1 是旧 VNode,n2 是新 VNode,container 是当前父容器(但 Teleport 会绕过它) - 内部调用
move(vnode, container, anchor)将子节点 DOM 移动到target - 使用
queuePostFlushCb延迟执行移动操作,避免因 DOM 尚未就绪导致失败
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










