From f46c73cc6c31802ea6209fb17db567ea4106ce54 Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 17:05:45 +0800 Subject: [PATCH] Match-id-734c7025e4bf66d1c909d3f3e46d57554e02aeb1 --- libs/horizon/src/renderer/vnode/VNode.ts | 131 +++++++++++++----- .../src/renderer/vnode/VNodeCreator.ts | 3 +- 2 files changed, 101 insertions(+), 33 deletions(-) diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index 1160681a..9f9a66c0 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -1,16 +1,17 @@ /** * 虚拟DOM结构体 */ -import {TreeRoot} from './VNodeTags'; -import type {VNodeTag} from './VNodeTags'; -import type {RefType, ContextType} from '../Types'; -import type {Hook} from '../hooks/HookType'; +import { TreeRoot, FunctionComponent, ClassComponent, DomPortal, DomText, ContextConsumer, ForwardRef, SuspenseComponent, LazyComponent, ClsOrFunComponent, DomComponent, Fragment, ContextProvider, Profiler, MemoComponent, IncompleteClassComponent } from './VNodeTags'; +import type { VNodeTag } from './VNodeTags'; +import type { RefType, ContextType } from '../Types'; +import type { Hook } from '../hooks/HookType'; export class VNode { tag: VNodeTag; key: string | null; // 唯一标识符 + props: any; // 传给组件的props的值,类组件包含defaultProps,Lazy组件不包含 type: any = null; - realNode: any = null; // 如果是类,则存放实例;如果是div这种,则存放真实DOM; + realNode: any; // 如果是类,则存放实例;如果是div这种,则存放真实DOM; // 关系结构 parent: VNode | null = null; // 父节点 @@ -20,21 +21,20 @@ export class VNode { eIndex: number = 0; // HorizonElement在jsx中的位置,例如:jsx中的null不会生成vNode,所以eIndex和cIndex不一致 ref: RefType | ((handle: any) => void) | null = null; // 包裹一个函数,submit阶段使用,比如将外部useRef生成的对象赋值到ref上 - props: any; // 传给组件的props的值,类组件包含defaultProps,Lazy组件不包含 oldProps: any = null; - suspensePromises: any = null; // suspense组件的promise列表 - changeList: any = null; // DOM的变更列表 - effectList: any[] | null = null; // useEffect 的更新数组 - updates: any[] | null = null; // TreeRoot和ClassComponent使用的更新数组 - stateCallbacks: any[] | null = null; // 存放存在setState的第二个参数和HorizonDOM.render的第三个参数所在的node数组 - isForceUpdate: boolean = false; // 是否使用强制更新 + suspensePromises: any; // suspense组件的promise列表 + changeList: any; // DOM的变更列表 + effectList: any[] | null; // useEffect 的更新数组 + updates: any[] | null; // TreeRoot和ClassComponent使用的更新数组 + stateCallbacks: any[] | null; // 存放存在setState的第二个参数和HorizonDOM.render的第三个参数所在的node数组 + isForceUpdate: boolean; // 是否使用强制更新 - state: any = null; // ClassComponent和TreeRoot的状态 - hooks: Array> | null = null; // 保存hook + state: any; // ClassComponent和TreeRoot的状态 + hooks: Array> | null; // 保存hook suspenseChildStatus: string = ''; // Suspense的Children是否显示 - depContexts: Array> | null = null; // FunctionComponent和ClassComponent对context的依赖列表 - isDepContextChange: boolean = false; // context是否变更 + depContexts: Array> | null; // FunctionComponent和ClassComponent对context的依赖列表 + isDepContextChange: boolean; // context是否变更 dirtyNodes: Array | null = null; // 需要改动的节点数组 shouldUpdate: boolean = false; childShouldUpdate: boolean = false; @@ -42,12 +42,12 @@ export class VNode { task: any; // 使用这个变量来记录修改前的值,用于恢复。 - contexts: any = null; + contexts: any; // 因为LazyComponent会修改tag和type属性,为了能识别,增加一个属性 - isLazyComponent: boolean = false; + isLazyComponent: boolean; // 因为LazyComponent会修改type属性,为了在diff中判断是否可以复用,需要增加一个lazyType - lazyType: any = null; + lazyType: any; flags: { Addition?: boolean; Update?: boolean; @@ -62,17 +62,17 @@ export class VNode { ForceUpdate?: boolean; Clear?: boolean; } = {}; - clearChild: VNode | null = null; + clearChild: VNode | null; // one tree相关属性 isCreated: boolean = true; - oldHooks: Array> | null = null; // 保存上一次执行的hook - oldState: any = null; + oldHooks: Array> | null; // 保存上一次执行的hook + oldState: any; oldRef: RefType | ((handle: any) => void) | null = null; - suspenseChildThrow = false; - oldSuspenseChildStatus: string = ''; // 上一次Suspense的Children是否显示 + suspenseChildThrow: boolean; + oldSuspenseChildStatus: string; // 上一次Suspense的Children是否显示 oldChild: VNode | null = null; - suspenseDidCapture: boolean = false; // suspense是否捕获了异常 - promiseResolve: boolean = false; // suspense的promise是否resolve + suspenseDidCapture: boolean; // suspense是否捕获了异常 + promiseResolve: boolean; // suspense的promise是否resolve path: string = ''; // 保存从根到本节点的路径 toUpdateNodes: Set; // 保存要更新的节点 @@ -85,11 +85,80 @@ export class VNode { this.props = props; - // 根节点 - if (tag === TreeRoot) { - this.outerDom = outerDom; - this.task = null; - this.toUpdateNodes = new Set(); + switch (tag) { + case TreeRoot: + this.outerDom = outerDom; + this.task = null; + this.toUpdateNodes = new Set(); + this.realNode = null; + this.updates = null; + this.stateCallbacks = null; + this.state = null; + this.oldState = null; + this.contexts = null; + break; + case FunctionComponent: + this.effectList = null; + this.hooks = null; + this.depContexts = null; + this.isDepContextChange = false; + this.oldHooks = null; + break; + case ClassComponent: + this.realNode = null; + this.updates = null; + this.stateCallbacks = null; + this.isForceUpdate = false; + this.state = null; + this.depContexts = null; + this.isDepContextChange = false; + this.oldState = null; + this.contexts = null; + break; + case ClsOrFunComponent: + this.realNode = null; + this.contexts = null; + break; + case DomPortal: + this.realNode = null; + this.contexts = null; + break; + case DomComponent: + this.realNode = null; + this.changeList = null; + this.contexts = null; + break; + case DomText: + this.realNode = null; + break; + case SuspenseComponent: + this.realNode = null; + this.suspensePromises = null; + this.suspenseChildThrow = false; + this.suspenseDidCapture = false; + this.promiseResolve = false; + this.oldSuspenseChildStatus = ''; + break; + case ContextProvider: + this.contexts = null; + break; + case MemoComponent: + this.effectList = null; + break; + case LazyComponent: + this.realNode = null; + this.stateCallbacks = null; + break; + case Fragment: + break; + case ContextConsumer: + break; + case ForwardRef: + break; + case Profiler: + break; + case IncompleteClassComponent: + break; } } } diff --git a/libs/horizon/src/renderer/vnode/VNodeCreator.ts b/libs/horizon/src/renderer/vnode/VNodeCreator.ts index 2d6d3bb2..ca585e5f 100644 --- a/libs/horizon/src/renderer/vnode/VNodeCreator.ts +++ b/libs/horizon/src/renderer/vnode/VNodeCreator.ts @@ -133,9 +133,8 @@ export function createUndeterminedVNode(type, key, props) { vNode.type = type; vNode.shouldUpdate = true; - // lazy类型的特殊处理 - vNode.isLazyComponent = isLazy; if (isLazy) { + vNode.isLazyComponent = isLazy; vNode.lazyType = type; } return vNode;