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