Match-id-b3144e462876f69f20c7c56f50a88fa9cd532298

This commit is contained in:
* 2022-01-25 09:33:01 +08:00 committed by *
parent c9948e796f
commit 356874599a
6 changed files with 74 additions and 8 deletions

View File

@ -16,7 +16,7 @@ import {
const prefix = '_horizon';
const internalKeys = {
export const internalKeys = {
VNode: `${prefix}VNode`,
props: `${prefix}Props`,
events: `${prefix}Events`,

View File

@ -1,7 +1,7 @@
import type { VNode } from '../Types';
import { FlagUtils } from '../vnode/VNodeFlags';
import { TYPE_COMMON_ELEMENT, TYPE_FRAGMENT, TYPE_PORTAL } from '../../external/JSXElementType';
import { DomText, DomPortal, Fragment } from '../vnode/VNodeTags';
import { DomText, DomPortal, Fragment, DomComponent } from '../vnode/VNodeTags';
import {updateVNode, createVNode, createVNodeFromElement, updateVNodePath} from '../vnode/VNodeCreator';
import {
isSameType,
@ -320,7 +320,13 @@ function diffArrayNodes(
// 3. 新节点已经处理完成
if (leftIdx === rightIdx) {
if (isComparing) {
deleteVNodes(parentNode, oldNode, rightEndOldNode);
if (firstChild && parentNode.tag === DomComponent && newChildren.length === 0) {
// if (false) {
FlagUtils.markClear(parentNode);
parentNode.ClearChild = firstChild;
} else {
deleteVNodes(parentNode, oldNode, rightEndOldNode);
}
}
if (rightNewNode) {

View File

@ -17,7 +17,7 @@ import {
SuspenseComponent,
MemoComponent,
} from '../vnode/VNodeTags';
import { FlagUtils, ResetText } from '../vnode/VNodeFlags';
import { FlagUtils, ResetText, Clear } from '../vnode/VNodeFlags';
import { mergeDefaultProps } from '../render/LazyComponent';
import {
submitDomUpdate,
@ -43,6 +43,7 @@ import {
findDomParent, getSiblingDom,
} from '../vnode/VNodeUtils';
import { shouldAutoFocus } from '../../dom/utils/Common';
import { internalKeys } from '../../dom/DOMInternalKeys';
function callComponentWillUnmount(vNode: VNode, instance: any) {
try {
@ -307,6 +308,55 @@ function unmountDomComponents(vNode: VNode): void {
});
}
function submitClear(vNode: VNode): void {
const realNode = vNode.realNode;
const cloneDom = realNode.cloneNode(false); // 复制节点后horizon的两个属性消失
cloneDom[internalKeys.VNode] = realNode[internalKeys.VNode];
cloneDom[internalKeys.props] = realNode[internalKeys.props];
// 删除节点
let currentParentIsValid = false;
// 这两个变量要一起更新
let currentParent;
travelVNodeTree(vNode, (node) => {
if (!currentParentIsValid) {
const parentObj = findDomParent(node);
currentParent = parentObj.parentDom;
currentParentIsValid = true;
}
const tag = node.tag;
if (tag === DomComponent || tag === DomText) {
// 卸载子vNode递归遍历子vNode
unmountNestedVNodes(node.ClearChild); // node.child 为空需要添加原有的child
// 在所有子项都卸载后删除dom树中的节点
removeChildDom(currentParent, node.realNode);
console.log(currentParent);
currentParent.append(cloneDom);
vNode.realNode = cloneDom;
FlagUtils.removeFlag(vNode, Clear);
vNode.ClearChild = null;
} else if (tag === DomPortal) {
console.log(DomPortal);
if (node.child !== null) {
currentParent = node.outerDom;
}
} else {
unmountVNode(node);
}
}, (node) => {
// 如果是dom不用再遍历child
const tag = node.tag;
return tag === DomComponent || tag === DomText;
}, null, (node) => {
if (node.tag === DomPortal) {
// 当离开portal需要重新设置parent
currentParentIsValid = false;
}
});
}
function submitDeletion(vNode: VNode): void {
// 遍历所有子节点删除dom节点detach ref 和 调用componentWillUnmount()
unmountDomComponents(vNode);
@ -353,6 +403,7 @@ export {
submitResetTextContent,
submitAddition,
submitDeletion,
submitClear,
submitUpdate,
callAfterSubmitLifeCycles,
attachRef,

View File

@ -9,7 +9,7 @@ import {
attachRef,
callAfterSubmitLifeCycles,
callBeforeSubmitLifeCycles, submitDeletion, submitAddition,
submitResetTextContent, submitUpdate, detachRef,
submitResetTextContent, submitUpdate, detachRef, submitClear,
} from './LifeCycleHandler';
import {tryRenderRoot, setProcessing} from '../TreeBuilder';
import {
@ -121,7 +121,7 @@ function submit(dirtyNodes: Array<VNode>) {
}
}
const {Addition, Update, Deletion} = node.flags;
const {Addition, Update, Deletion, Clear} = node.flags;
if (Addition && Update) {
// Addition
submitAddition(node);
@ -138,6 +138,9 @@ function submit(dirtyNodes: Array<VNode>) {
} else if (Deletion) {
submitDeletion(node);
}
if (Clear) {
submitClear(node);
}
}
} catch (error) {
throwIfTrue(node === null, 'Should be working on an effect.');

View File

@ -60,8 +60,9 @@ export class VNode {
Interrupted?: boolean;
ShouldCapture?: boolean;
ForceUpdate?: boolean;
Clear?: boolean;
} = {};
ClearChild: VNode|null = null;
// one tree相关属性
isCreated: boolean = true;
oldHooks: Array<Hook<any, any>> = []; // 保存上一次执行的hook

View File

@ -18,9 +18,10 @@ export const Interrupted = 'Interrupted';
export const ShouldCapture = 'ShouldCapture';
// For suspense
export const ForceUpdate = 'ForceUpdate';
export const Clear = 'Clear';
const FlagArr = [Addition, Update, Deletion, ResetText, Callback,
DidCapture, Ref, Snapshot, Interrupted, ShouldCapture, ForceUpdate];
DidCapture, Ref, Snapshot, Interrupted, ShouldCapture, ForceUpdate, Clear];
const LifecycleEffectArr = [Update, Callback, Ref, Snapshot];
@ -90,5 +91,9 @@ export class FlagUtils {
static markForceUpdate(node: VNode) {
node.flags.ForceUpdate = true;
}
static markClear(node: VNode) {
node.flags.Clear = true;
}
}