From 3a242e79213bad735dd18b5d39e9c706bc115587 Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 20:20:38 +0800 Subject: [PATCH] Match-id-f9204abb03ec4372ff212799440e0c744b176e36 --- libs/horizon/src/renderer/TreeBuilder.ts | 23 +++++--- .../src/renderer/submit/LifeCycleHandler.ts | 52 ++++++++++++++++--- libs/horizon/src/renderer/vnode/VNodeUtils.ts | 18 ------- 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts index 0f13627d..76de8ae4 100644 --- a/libs/horizon/src/renderer/TreeBuilder.ts +++ b/libs/horizon/src/renderer/TreeBuilder.ts @@ -2,7 +2,7 @@ import type { VNode } from './Types'; import { callRenderQueueImmediate, pushRenderCallback } from './taskExecutor/RenderQueue'; import { updateVNode } from './vnode/VNodeCreator'; -import { TreeRoot } from './vnode/VNodeTags'; +import { TreeRoot, DomComponent, DomPortal } from './vnode/VNodeTags'; import { FlagUtils, InitFlag, Interrupted } from './vnode/VNodeFlags'; import { captureVNode } from './render/BaseComponent'; import { checkLoopingUpdateLimit, submitToRender } from './submit/Submit'; @@ -18,7 +18,6 @@ import { setProcessingClassVNode, setStartVNode } from './GlobalVar'; -import { findDomParent } from './vnode/VNodeUtils'; import { ByAsync, BySync, @@ -223,13 +222,21 @@ function buildVNodeTree(treeRoot: VNode) { if (startVNode.tag !== TreeRoot) { // 不是根节点 // 设置namespace,用于createElement - const parentObj = findDomParent(startVNode); - + let parent = startVNode.parent; + while (parent !== null) { + const tag = parent.tag; + if (tag === DomComponent) { + break; + } else if (tag === TreeRoot || tag === DomPortal) { + break; + } + parent = parent.parent; + } + // 当在componentWillUnmount中调用setState,parent可能是null,因为startVNode会被clear - if (parentObj !== null) { - const domParent = parentObj.parent; - resetNamespaceCtx(domParent); - setNamespaceCtx(domParent, domParent.outerDom); + if (parent !== null) { + resetNamespaceCtx(parent); + setNamespaceCtx(parent, parent.outerDom); } // 恢复父节点的context diff --git a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts index 55edf2c7..a9d8344d 100644 --- a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts +++ b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts @@ -39,7 +39,7 @@ import { travelVNodeTree, clearVNode, isDomVNode, - findDomParent, getSiblingDom, + getSiblingDom, } from '../vnode/VNodeUtils'; import { shouldAutoFocus } from '../../dom/utils/Common'; @@ -220,7 +220,20 @@ function unmountNestedVNodes(vNode: VNode): void { } function submitAddition(vNode: VNode): void { - const { parent, parentDom } = findDomParent(vNode); + let parent = vNode.parent; + let parentDom; + let tag; + while (parent !== null) { + tag = parent.tag; + if (tag === DomComponent) { + parentDom = parent.realNode; + break; + } else if (tag === TreeRoot || tag === DomPortal) { + parentDom = parent.outerDom; + break; + } + parent = parent.parent; + } if ((vNode.flags & ResetText) === ResetText) { // 在insert之前先reset @@ -270,8 +283,19 @@ function unmountDomComponents(vNode: VNode): void { travelVNodeTree(vNode, (node) => { if (!currentParentIsValid) { - const parentObj = findDomParent(node); - currentParent = parentObj.parentDom; + let parent = node.parent; + let tag; + while (parent !== null) { + tag = parent.tag; + if (tag === DomComponent) { + currentParent = parent.realNode; + break; + } else if (tag === TreeRoot || tag === DomPortal) { + currentParent = parent.outerDom; + break; + } + parent = parent.parent; + } currentParentIsValid = true; } @@ -315,8 +339,20 @@ function submitClear(vNode: VNode): void { } } - const parentObj = findDomParent(vNode); - const currentParent = parentObj.parentDom; + let parent = vNode.parent; + let parentDom; + let tag; + while (parent !== null) { + tag = parent.tag; + if (tag === DomComponent) { + parentDom = parent.realNode; + break; + } else if (tag === TreeRoot || tag === DomPortal) { + parentDom = parent.outerDom; + break; + } + parent = parent.parent; + } let clearChild = vNode.clearChild as VNode; // 上次渲染的child保存在clearChild属性中 // 卸载 clearChild 和 它的兄弟节点 while(clearChild) { @@ -327,9 +363,9 @@ function submitClear(vNode: VNode): void { } // 在所有子项都卸载后,删除dom树中的节点 - removeChildDom(currentParent, vNode.realNode); + removeChildDom(parentDom, vNode.realNode); const realNodeNext = getSiblingDom(vNode); - insertDom(currentParent, cloneDom, realNodeNext); + insertDom(parentDom, cloneDom, realNodeNext); vNode.realNode = cloneDom; attachRef(vNode); FlagUtils.removeFlag(vNode, Clear); diff --git a/libs/horizon/src/renderer/vnode/VNodeUtils.ts b/libs/horizon/src/renderer/vnode/VNodeUtils.ts index c9d4b572..cc56591c 100644 --- a/libs/horizon/src/renderer/vnode/VNodeUtils.ts +++ b/libs/horizon/src/renderer/vnode/VNodeUtils.ts @@ -114,24 +114,6 @@ function isDomContainer(vNode: VNode): boolean { ); } -// 找到DOM类型的父 -export function findDomParent(vNode: VNode) { - let parent = vNode.parent; - - while (parent !== null) { - switch (parent.tag) { - case DomComponent: - return {parent, parentDom: parent.realNode}; - case TreeRoot: - case DomPortal: - return {parent, parentDom: parent.outerDom}; - } - parent = parent.parent; - } - - return null; -} - export function findDomVNode(vNode: VNode): VNode | null { return travelVNodeTree(vNode, (node) => { if (node.tag === DomComponent || node.tag === DomText) {