Match-id-f9204abb03ec4372ff212799440e0c744b176e36

This commit is contained in:
* 2022-02-17 20:20:38 +08:00 committed by *
parent b0c3086a77
commit 3a242e7921
3 changed files with 59 additions and 34 deletions

View File

@ -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中调用setStateparent可能是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

View File

@ -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);

View File

@ -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) {