Teleport场景及原理
Vue 3 的 Teleport 组件
使用场景
组件用于将某些 DOM 结构渲染到 Vue 组件树外的特定 DOM 位置。常见的应用场景包括:
-
模态框(Modal)
需要将模态框渲染到 body 之外,避免受到 overflow: hidden 或 z-index 影响。 -
通知(Notification)
例如全局消息提示,通常希望它们直接挂载到 document.body,避免层级问题。 -
悬浮内容(Dropdown、Tooltip)
这些组件可能会受父级 overflow: hidden 影响,使用 teleport 可让它们脱离当前层级。 -
固定 UI 组件
例如全局浮动按钮、右下角聊天窗口等,避免受父组件影响。
基本用法
这是一个 Teleport 传送的模态框
以上代码会将
底层实现
- 解析过程
在 Vue 3 的虚拟 DOM 渲染过程中,Teleport 组件会在 patch 阶段 处理 VNode,并将其内容渲染到 to 指定的 DOM 位置,而非原组件层级。
- 挂载阶段
Vue 在 setupRenderEffect 过程中会调用 processTeleport 处理 Teleport 节点。
Teleport 组件不会直接渲染其 children,而是会:
-
先找到目标 to(默认 body)。
-
把子元素 children 移动 到目标 to 位置。
关键代码:
function processTeleport(
n1: VNode | null,
n2: VNode,
container: RendererElement,
parentComponent: ComponentInternalInstance | null
) {
const target = resolveTarget(n2.props!.to); // 解析目标 DOM
if (target) {
target.appendChild(n2.el);
}
}
- 更新阶段
当 Teleport 的 children 发生变化时:
Vue 不会 直接更新 Teleport 本身,而是 更新目标 DOM 位置的内容,避免不必要的重新渲染。
如果 to 发生变化,Vue 会将内容从旧 to 迁移到新的 to。
- 卸载阶段
当 Teleport 组件卸载时,会清理其 children 并移除目标 DOM 位置的内容。
总结
作用:Teleport 允许 Vue 组件的部分 DOM 结构被渲染到 Vue 组件树之外的指定位置。
实现原理:
-
解析 to 指定的目标 DOM。
-
挂载时,将 children 直接移动到 to 目标位置。
-
更新时,修改目标位置的内容而不重新渲染 Teleport 本身。
-
卸载时清理 children,防止 DOM 残留。
Teleport 主要用于处理模态框、弹出层等不受父组件影响的 UI 组件,是 Vue 3 提供的一个强大特性。