当前位置:   article > 正文

vue3特性-Teleport源码

vue3特性-Teleport源码


前言

TeleportVue 3 的一个内置组件,它允许你将组件的内容渲染到 DOM 树的其他位置,而不是其父组件的 DOM 层次结构中。下面是对 Teleport 实现源码的详细分析。

源码分析

我们可以在 Vue 3 的源码中找到 Teleport 的实现,主要在 runtime-core 包中。以下是 Teleport 组件的主要部分(完整代码 Teleport.ts):

1. Teleport 组件定义

runtime-core/src/components/Teleport.ts 中定义了 Teleport 组件:

import {
  RendererElement,
  RendererNode,
  RendererInternals,
  TransformVNodeArgs,
  VNode,
  TeleportProps
} from '../renderer';
import { isFunction, isArray, isString } from '@vue/shared';

// TeleportComponent
export const TeleportImpl = {
  __isTeleport: true,
  process(
    n1: VNode | null,
    n2: VNode,
    container: RendererElement,
    anchor: RendererNode | null,
    internals: RendererInternals,
    optimized: boolean
  ) {
    // 处理逻辑
  },
  remove(vnode: VNode, internals: RendererInternals) {
    // 移除逻辑
  },
  move(vnode: VNode, container: RendererElement, anchor: RendererNode | null, internals: RendererInternals) {
    // 移动逻辑
  },
  hydrate: null // SSR 相关逻辑
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
2. process 方法

process 方法是 Teleport 的核心,用于处理 VNode 的挂载、更新和卸载逻辑:

process(
  n1: VNode | null,
  n2: VNode,
  container: RendererElement,
  anchor: RendererNode | null,
  internals: RendererInternals,
  optimized: boolean
) {
  const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText } } = internals;
  const target = n2.props && n2.props.to;

  if (n1 == null) {
    // 初始化逻辑
    if (target != null) {
      const targetNode = isString(target) ? querySelector(target) : target;
      if (targetNode) {
        mountChildren(n2.children, targetNode, anchor, internals, optimized);
      }
    }
  } else {
    // 更新逻辑
    if (target !== (n1.props && n1.props.to)) {
      // 目标位置变化时的处理
    }
    patchChildren(n1, n2, container, anchor, internals, optimized);
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
3. 挂载逻辑

process 方法中,如果 n1null,表示这是第一次挂载组件。此时 Teleport 会将其子组件挂载到指定的目标容器中:

if (n1 == null) {
  // 初始化逻辑
  if (target != null) {
    const targetNode = isString(target) ? querySelector(target) : target;
    if (targetNode) {
      mountChildren(n2.children, targetNode, anchor, internals, optimized);
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
4. 更新逻辑

如果 n1 不为 null,则表示这是一次更新。Teleport 会检查目标位置是否发生变化,并根据需要移动子组件:

if (target !== (n1.props && n1.props.to)) {
  // 目标位置变化时的处理
}
patchChildren(n1, n2, container, anchor, internals, optimized);
  • 1
  • 2
  • 3
  • 4
5. 移除和移动逻辑

removemove 方法分别处理组件从目标位置移除和在目标位置之间移动的逻辑:

remove(vnode: VNode, internals: RendererInternals) {
  // 移除逻辑
},
move(vnode: VNode, container: RendererElement, anchor: RendererNode | null, internals: RendererInternals) {
  // 移动逻辑
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

总结

Teleport 通过其 process 方法处理挂载、更新和移除逻辑,确保子组件可以正确地在指定的目标位置渲染和更新。其核心机制包括:

  • 挂载时查找目标位置并将子组件插入其中。
  • 更新时检查目标位置变化并根据需要移动子组件。
  • 处理子组件的移除和移动。

Teleport 的实现充分利用了 Vue 的虚拟 DOM 和渲染机制,使其能够灵活地控制组件的渲染位置,满足复杂的 UI 需求。

参考资料

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/746903
推荐阅读
相关标签
  

闽ICP备14008679号