Match-id-3d913d35f0eb68f4d311fcf073625132167ca7b4
This commit is contained in:
parent
cbd821aed3
commit
ed2f6e8df5
|
@ -86,7 +86,7 @@ function collectDirtyNodes(vNode: VNode, parent: VNode): void {
|
|||
if (parent.dirtyNodes === null) {
|
||||
parent.dirtyNodes = dirtyNodes;
|
||||
} else {
|
||||
parent.dirtyNodes.push(...vNode.dirtyNodes);
|
||||
parent.dirtyNodes.push(...dirtyNodes);
|
||||
dirtyNodes.length = 0;
|
||||
}
|
||||
vNode.dirtyNodes = null;
|
||||
|
@ -105,7 +105,7 @@ function collectDirtyNodes(vNode: VNode, parent: VNode): void {
|
|||
|
||||
// 尝试完成当前工作单元,然后移动到下一个兄弟工作单元。如果没有更多的同级,请返回父vNode。
|
||||
function bubbleVNode(vNode: VNode): void {
|
||||
let node = vNode;
|
||||
let node : VNode | null = vNode;
|
||||
|
||||
do {
|
||||
const parent = node.parent;
|
||||
|
@ -182,14 +182,18 @@ function isEqualByIndex(idx: number, pathArrays: string[][]) {
|
|||
function getChildByIndex(vNode: VNode, idx: number) {
|
||||
let node = vNode.child;
|
||||
for (let i = 0; i < idx; i++) {
|
||||
node = node.next;
|
||||
if (node) {
|
||||
node = node.next;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// 从多个更新节点中,计算出开始节点。即:找到最近的共同的父辈节点
|
||||
export function calcStartUpdateVNode(treeRoot: VNode) {
|
||||
const toUpdateNodes = Array.from(treeRoot.toUpdateNodes);
|
||||
const toUpdateNodes = Array.from(treeRoot.toUpdateNodes!);
|
||||
|
||||
if (toUpdateNodes.length === 0) {
|
||||
return treeRoot;
|
||||
|
@ -218,12 +222,12 @@ export function calcStartUpdateVNode(treeRoot: VNode) {
|
|||
// 得到相等的路径
|
||||
const startNodePath = pathArrays[0].slice(0, commonPathEndIndex);
|
||||
|
||||
let node = treeRoot;
|
||||
let node: VNode | null = treeRoot;
|
||||
for (let i = 1; i < startNodePath.length; i++) {
|
||||
const pathIndex = Number(startNodePath[i]);
|
||||
node = getChildByIndex(node, pathIndex)!;
|
||||
node = getChildByIndex(node, pathIndex);
|
||||
// 路径错误时,回退到从根更新
|
||||
if (node == null) {
|
||||
if (node === null) {
|
||||
return treeRoot;
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +246,7 @@ function buildVNodeTree(treeRoot: VNode) {
|
|||
setStartVNode(startVNode);
|
||||
|
||||
// 清空toUpdateNodes
|
||||
treeRoot.toUpdateNodes.clear();
|
||||
treeRoot.toUpdateNodes!.clear();
|
||||
|
||||
if (startVNode.tag !== TreeRoot) { // 不是根节点
|
||||
// 设置namespace,用于createElement
|
||||
|
|
|
@ -24,13 +24,7 @@ import {
|
|||
createPortalVNode,
|
||||
createDomTextVNode,
|
||||
} from '../vnode/VNodeCreator';
|
||||
import {
|
||||
isSameType,
|
||||
getIteratorFn,
|
||||
isTextType,
|
||||
isIteratorType,
|
||||
isObjectType,
|
||||
} from './DiffTools';
|
||||
import { isSameType, getIteratorFn, isTextType, isIteratorType, isObjectType } from './DiffTools';
|
||||
import { travelChildren } from '../vnode/VNodeUtils';
|
||||
import { markVNodePath } from '../utils/vNodePath';
|
||||
|
||||
|
@ -120,10 +114,12 @@ function getNodeType(newChild: any): string | null {
|
|||
function setVNodeAdditionFlag(newNode: VNode, lastPosition: number): number {
|
||||
let position = lastPosition;
|
||||
|
||||
if (newNode.isCreated || newNode.eIndex < lastPosition) { // 位置 小于 上一个复用的位置
|
||||
if (newNode.isCreated || newNode.eIndex < lastPosition) {
|
||||
// 位置 小于 上一个复用的位置
|
||||
// 标记为新增
|
||||
FlagUtils.setAddition(newNode);
|
||||
} else { // 复用
|
||||
} else {
|
||||
// 复用
|
||||
position = newNode.eIndex;
|
||||
}
|
||||
|
||||
|
@ -206,15 +202,16 @@ function transRightChildrenToArray(child) {
|
|||
return rightChildrenArray;
|
||||
}
|
||||
|
||||
function transLeftChildrenToMap(
|
||||
startChild: VNode,
|
||||
rightEndVNode: VNode | null,
|
||||
): Map<string | number, VNode> {
|
||||
function transLeftChildrenToMap(startChild: VNode, rightEndVNode: VNode | null): Map<string | number, VNode> {
|
||||
const leftChildrenMap: Map<string | number, VNode> = new Map();
|
||||
|
||||
travelChildren(startChild, node => {
|
||||
leftChildrenMap.set(node.key !== null ? node.key : node.eIndex, node);
|
||||
}, node => node === rightEndVNode);
|
||||
travelChildren(
|
||||
startChild,
|
||||
node => {
|
||||
leftChildrenMap.set(node.key !== null ? node.key : node.eIndex, node);
|
||||
},
|
||||
node => node === rightEndVNode
|
||||
);
|
||||
|
||||
return leftChildrenMap;
|
||||
}
|
||||
|
@ -235,11 +232,7 @@ function getOldNodeFromMap(nodeMap: Map<string | number, VNode>, newIdx: number,
|
|||
}
|
||||
|
||||
// diff数组类型的节点,核心算法
|
||||
function diffArrayNodesHandler(
|
||||
parentNode: VNode,
|
||||
firstChild: VNode | null,
|
||||
newChildren: Array<any>,
|
||||
): VNode | null {
|
||||
function diffArrayNodesHandler(parentNode: VNode, firstChild: VNode | null, newChildren: Array<any>): VNode | null {
|
||||
let resultingFirstChild: VNode | null = null;
|
||||
|
||||
let prevNewNode: VNode | null = null;
|
||||
|
@ -358,7 +351,7 @@ function diffArrayNodesHandler(
|
|||
|
||||
if (rightNewNode) {
|
||||
appendNode(rightNewNode);
|
||||
setVNodesCIndex(rightNewNode, prevNewNode.cIndex + 1);
|
||||
setVNodesCIndex(rightNewNode, rightNewNode.cIndex + 1);
|
||||
}
|
||||
|
||||
return resultingFirstChild;
|
||||
|
@ -366,13 +359,14 @@ function diffArrayNodesHandler(
|
|||
|
||||
// 4. 新节点还有一部分,但是老节点已经没有了
|
||||
if (oldNode === null) {
|
||||
|
||||
let isDirectAdd = false;
|
||||
// TODO: 是否可以扩大至非dom类型节点
|
||||
// 如果dom节点在上次添加前没有节点,说明本次添加时,可以直接添加到最后,不需要通过 getSiblingDom 函数找到 before 节点
|
||||
if (parentNode.tag === DomComponent &&
|
||||
if (
|
||||
parentNode.tag === DomComponent &&
|
||||
parentNode.oldProps?.children?.length === 0 &&
|
||||
rightIdx - leftIdx === newChildren.length) {
|
||||
rightIdx - leftIdx === newChildren.length
|
||||
) {
|
||||
isDirectAdd = true;
|
||||
}
|
||||
const isAddition = parentNode.tag === DomPortal || !parentNode.isCreated;
|
||||
|
@ -424,7 +418,8 @@ function diffArrayNodesHandler(
|
|||
const eIndex = newNode.eIndex;
|
||||
eIndexes.push(eIndex);
|
||||
last = eIndexes[result[result.length - 1]];
|
||||
if (eIndex > last || last === undefined) { // 大的 eIndex直接放在最后
|
||||
if (eIndex > last || last === undefined) {
|
||||
// 大的 eIndex直接放在最后
|
||||
preIndex[i] = result[result.length - 1];
|
||||
result.push(i);
|
||||
} else {
|
||||
|
@ -500,13 +495,13 @@ function setVNodesCIndex(startChild: VNode | null, startIdx: number) {
|
|||
function diffIteratorNodesHandler(
|
||||
parentNode: VNode,
|
||||
firstChild: VNode | null,
|
||||
newChildrenIterable: Iterable<any>,
|
||||
newChildrenIterable: Iterable<any>
|
||||
): VNode | null {
|
||||
const iteratorFn = getIteratorFn(newChildrenIterable);
|
||||
const iteratorObj = iteratorFn.call(newChildrenIterable);
|
||||
const iteratorObj: Iterator<any> = iteratorFn.call(newChildrenIterable);
|
||||
|
||||
// 把iterator转测数组
|
||||
const childrenArray = [];
|
||||
const childrenArray: any[] = [];
|
||||
let result = iteratorObj.next();
|
||||
while (!result.done) {
|
||||
childrenArray.push(result.value);
|
||||
|
@ -517,12 +512,7 @@ function diffIteratorNodesHandler(
|
|||
}
|
||||
|
||||
// 新节点是字符串类型
|
||||
function diffStringNodeHandler(
|
||||
parentNode: VNode,
|
||||
newChild: any,
|
||||
firstChildVNode: VNode,
|
||||
isComparing: boolean
|
||||
) {
|
||||
function diffStringNodeHandler(parentNode: VNode, newChild: any, firstChildVNode: VNode | null, isComparing: boolean) {
|
||||
let newTextNode: VNode | null = null;
|
||||
|
||||
// 第一个vNode是Text,则复用
|
||||
|
@ -550,7 +540,6 @@ function diffObjectNodeHandler(
|
|||
parentNode: VNode,
|
||||
firstChild: VNode | null,
|
||||
newChild: any,
|
||||
firstChildVNode: VNode,
|
||||
isComparing: boolean
|
||||
) {
|
||||
let canReuseNode: VNode | null = null;
|
||||
|
@ -569,7 +558,7 @@ function diffObjectNodeHandler(
|
|||
}
|
||||
|
||||
let resultNode: VNode | null = null;
|
||||
let startDelVNode = firstChildVNode;
|
||||
let startDelVNode: VNode | null = firstChild;
|
||||
if (newChild.vtype === TYPE_COMMON_ELEMENT) {
|
||||
if (canReuseNode) {
|
||||
// 可以复用
|
||||
|
@ -664,7 +653,7 @@ export function createChildrenByDiff(
|
|||
|
||||
// 5. newChild是对象类型
|
||||
if (isObjectType(newChild)) {
|
||||
const newVNodes = diffObjectNodeHandler(parentNode, firstChild, newChild, firstChild, isComparing);
|
||||
const newVNodes = diffObjectNodeHandler(parentNode, firstChild, newChild, isComparing);
|
||||
if (newVNodes) {
|
||||
return newVNodes;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue