Repository: vuejs/vue-next
File: packages/runtime-vapor/src/components/Teleport.ts (TypeScript)

Code before:

    if (!isHydrating) {
      this.initChildren()
    }
  }

  get parent(): ParentNode | null {
    return this.anchor ? this.anchor.parentNode : null
  }

  private initChildren(): void {
    renderEffect(() => {
      this.handleChildrenUpdate(
        this.rawSlots!.default && (this.rawSlots!.default as BlockFn)(),
      )
    })

    const nodes = this.nodes
    // register updateCssVars to root fragments's update hooks so that
    // it will be called when root fragment changed
    if (this.parentComponent && this.parentComponent.ut) {
      if (isFragment(nodes)) {
        ;(nodes.onUpdated || (nodes.onUpdated = [])).push(() =>
          updateCssVars(this),
        )
      } else if (isVaporComponent(nodes) && isFragment(nodes.block)) {
        ;(nodes.block.onUpdated || (nodes.block.onUpdated = [])).push(() =>
          updateCssVars(this),
        )
      } else if (isArray(nodes)) {
        nodes.forEach(node => {
          if (isFragment(node)) {
            ;(node.onUpdated || (node.onUpdated = [])).push(() =>
              updateCssVars(this),
            )
          }
        })
      }
    }

    if (__DEV__) {
      if (isVaporComponent(nodes)) {
        nodes.parentTeleport = this
      } else if (isArray(nodes)) {
        nodes.forEach(
          node => isVaporComponent(node) && (node.parentTeleport = this),
        )
      }
    }
  }


Review comment (suggestion):
should consider recursively processing child nodes
see [repl with this PR](https://deploy-preview-14284--vue-sfc-playground.netlify.app/#eNp9U01PwzAM/Sshl4IE6wFOo5v4EAc4AAKOuXStNwJpEiVuGZr237HTbkyI7dLE773YL467ktfej7oW5FgWsQrao4iArRdd6V2YKqsbWlGsRIC5WIt5cI3I6EC2pW5d4wd8lHPA+YhWtnI2oqiccUFMOMFxFqDOTjZMfHdfA4GhBcKLvDdBhSlAaLwpESgSopi1iM6Kq8ro6nOi5HD6iFclpwku8l7Vn3gDA8kiOtLPXP1NOmaYC6WNGvWgTRib30YUR19a0Z3p+STjItmUAbJI311ZrTtSgYkwpW2R0+c3Z+rIpmj+pyoBg0UKi3znvkXEb8MbTr5ibWrjmArNtK2PU3Ryqew6NS2J5anESJ2d68XoIzpLb5pOKlmRB20gPHkuHZUc9zmZK41xXw8J40c43eDVO1Sf/+AfccmYks8BIoQOlNxyWIYFYE/fvT7CkvZbsnF1a0h9gHyB6EzLHnvZTWtrsr2jS27v0+Bpu3iLd0sE6uhwKTbKynXSK0mDyO3fd/Vfu+eji3SO+kld3Azxnp/iwJDy0BiHIv/7nnL9AwiQIkU=)

Code after:

    if (!isHydrating) {
      this.initChildren()
    }
  }

  get parent(): ParentNode | null {
    return this.anchor ? this.anchor.parentNode : null
  }

  private initChildren(): void {
    renderEffect(() => {
      this.handleChildrenUpdate(
        this.rawSlots!.default && (this.rawSlots!.default as BlockFn)(),
      )
    })
    const nodes = this.nodes

    // register updateCssVars to nested fragments's update hooks so that
    // it will be called when root fragment changed
    if (this.parentComponent && this.parentComponent.ut) {
      this.registerUpdateCssVars(nodes)
    }

    if (__DEV__) {
      if (isVaporComponent(nodes)) {
        nodes.parentTeleport = this
      } else if (isArray(nodes)) {
        nodes.forEach(
          node => isVaporComponent(node) && (node.parentTeleport = this),
        )
      }
    }
  }

  private registerUpdateCssVars(block: Block) {
    if (isFragment(block)) {
      ;(block.onUpdated || (block.onUpdated = [])).push(() =>
        updateCssVars(this),
      )
      this.registerUpdateCssVars(block.nodes)
    } else if (isVaporComponent(block)) {
      this.registerUpdateCssVars(block.block)
    } else if (isArray(block)) {
      block.forEach(node => this.registerUpdateCssVars(node))
    }
  }

  private handleChildrenUpdate(children: Block): void {
    // not mounted yet
    if (!this.parent || isHydrating) {