14.2.1 Teleport 组件要解决的问题
Teleport(传送)把组件逻辑上的归属与实际渲染位置解耦:内容仍写在模板的某个位置,但最终渲染到
to指定的容器里,从而摆脱 DOM 层级的限制。
一、只有「逻辑归属」,不够
模板天生是树形结构,子节点只能渲染在父节点的容器里。但有些 UI 的渲染位置必须跳出去:
- 全屏弹窗 / 遮罩层(overlay)需要挂到
body下,才能不受父级层级、定位、裁剪的影响; - 父级若出现
overflow: hidden、transform、z-index之类的样式,弹窗会被裁剪或被压在下面; - 有些场景只是希望 DOM 结构挂在别处(例如第三方库要求容器)而逻辑仍属于当前组件(状态、props、事件都还在原组件里)。
二、一个典型场景
<template>
<Teleport to="body">
<div class="overlay"></div>
</Teleport>
</template>
<style scoped>
.overlay {
z-index: 9999;
}
</style>
<Teleport>的插槽内容就是被传送的内容;to="body"指定渲染目标,于是.overlay直接成为body的子节点,而不会按照模板的 DOM 层级挂在组件所在的位置;- 这样就实现了跨 DOM 层级的渲染,
z-index: 9999也能真正生效。
关键区别:组件的状态与逻辑仍在原组件内部,只是渲染出的 DOM 换了位置。
三、要点
| 关注点 | 说明 |
|---|---|
| 解决什么 | 逻辑归属与渲染位置分离,规避父容器的层级 / 裁剪 / 定位限制 |
| 怎么指定位置 | to:可以是 CSS 选择器字符串(如 'body'、'#app'),也可以是容器元素本身 |
| 子节点如何编译 | Teleport 的子节点直接编译为一个数组,而不是普通组件的插槽对象 |
| 更新时 | 子节点更新走 patchChildren,还要额外考虑 to 变化的情况(内容需要换容器) |
相关
- 14.2.2 实现 Teleport 组件:识别
__isTeleport标识、把渲染逻辑交接给process函数并实现挂载 / 更新