Match-id-abcf03478cbcdf950f7350df7f2e23add28411d0

This commit is contained in:
* 2022-11-08 10:29:40 +08:00 committed by *
parent 9075dbe1b2
commit 805f59c8fe
2 changed files with 147 additions and 250 deletions

View File

@ -81,7 +81,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(...dirtyNodes); parent.dirtyNodes.push(...vNode.dirtyNodes);
dirtyNodes.length = 0; dirtyNodes.length = 0;
} }
vNode.dirtyNodes = null; vNode.dirtyNodes = null;
@ -100,7 +100,7 @@ function collectDirtyNodes(vNode: VNode, parent: VNode): void {
// 尝试完成当前工作单元然后移动到下一个兄弟工作单元。如果没有更多的同级请返回父vNode。 // 尝试完成当前工作单元然后移动到下一个兄弟工作单元。如果没有更多的同级请返回父vNode。
function bubbleVNode(vNode: VNode): void { function bubbleVNode(vNode: VNode): void {
let node: VNode | null = vNode; let node = vNode;
do { do {
const parent = node.parent; const parent = node.parent;
@ -179,18 +179,14 @@ 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 !== null) {
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;
@ -219,12 +215,12 @@ export function calcStartUpdateVNode(treeRoot: VNode) {
// 得到相等的路径 // 得到相等的路径
const startNodePath = pathArrays[0].slice(0, commonPathEndIndex); const startNodePath = pathArrays[0].slice(0, commonPathEndIndex);
let node: VNode | null = treeRoot; let node = 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;
} }
} }
@ -243,7 +239,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) {
// 不是根节点 // 不是根节点
@ -351,10 +347,16 @@ function renderFromRoot(treeRoot) {
// 2. 提交变更 // 2. 提交变更
submitToRender(treeRoot); submitToRender(treeRoot);
popCurrentRoot(); popCurrentRoot();
if (window.__HORIZON_DEV_HOOK__) {
// 与Devtool通信 const hook = window.__HORIZON_DEV_HOOK__;
sendRootToDevTool(treeRoot); // injector.js 可能在 Horizon 代码之后加载,此时无 __HORIZON_DEV_HOOK__ 全局变量
// Horizon 代码初次加载时不会初始化 helper
if (!hook.isInit) {
injectUpdater();
}
hook.addIfNotInclude(treeRoot);
hook.send(treeRoot);
}
return null; return null;
} }
@ -401,25 +403,6 @@ export function launchUpdateFromVNode(vNode: VNode) {
} }
} }
declare global {
interface Window {
__HORIZON_DEV_HOOK__: any;
}
}
function sendRootToDevTool(treeRoot) {
if (window.__HORIZON_DEV_HOOK__) {
const hook = window.__HORIZON_DEV_HOOK__;
// injector.js 可能在 Horizon 代码之后加载,此时无 __HORIZON_DEV_HOOK__ 全局变量
// Horizon 代码初次加载时不会初始化 helper
if (!hook.isInit) {
injectUpdater();
}
hook.addIfNotInclude(treeRoot);
hook.send(treeRoot);
}
}
// ============================== HorizonDOM使用 ============================== // ============================== HorizonDOM使用 ==============================
export function runDiscreteUpdates() { export function runDiscreteUpdates() {
if (checkMode(ByAsync) || checkMode(InRender)) { if (checkMode(ByAsync) || checkMode(InRender)) {

View File

@ -34,13 +34,6 @@ enum DiffCategory {
ARR_NODE = 'ARR_NODE', ARR_NODE = 'ARR_NODE',
} }
type AppendVNode = (vnode: VNode) => void;
interface DiffRightSideResult {
rightIdx: number;
rightEndOldNode: VNode;
rightNewNode: VNode | null;
}
// 检查是不是被 FRAGMENT 包裹 // 检查是不是被 FRAGMENT 包裹
function isNoKeyFragment(child: any) { function isNoKeyFragment(child: any) {
return child != null && child.type === TYPE_FRAGMENT && child.key === null; return child != null && child.type === TYPE_FRAGMENT && child.key === null;
@ -118,12 +111,19 @@ function getNodeType(newChild: any): string | null {
} }
// 设置vNode的flag // 设置vNode的flag
function setVNodeAdditionFlag(newNode: VNode) { function setVNodeAdditionFlag(newNode: VNode, lastPosition: number): number {
if (newNode.isCreated) { let position = lastPosition;
if (newNode.isCreated || newNode.eIndex < lastPosition) {
// 位置 小于 上一个复用的位置 // 位置 小于 上一个复用的位置
// 标记为新增 // 标记为新增
FlagUtils.setAddition(newNode); FlagUtils.setAddition(newNode);
} else {
// 复用
position = newNode.eIndex;
} }
return position;
} }
// 获取新节点 // 获取新节点
@ -231,75 +231,74 @@ function getOldNodeFromMap(nodeMap: Map<string | number, VNode>, newIdx: number,
return null; return null;
} }
/** // diff数组类型的节点核心算法
* function diffArrayNodesHandler(parentNode: VNode, firstChild: VNode | null, newChildren: Array<any>): VNode | null {
* @param firstNode VNode let resultingFirstChild: VNode | null = null;
* @param newChildren JSX children
* @param parentNode let prevNewNode: VNode | null = null;
* @param appendNode
*/ let oldNode = firstChild;
function diffLeftSide(firstNode: VNode | null, newChildren: Array<any>, parentNode: VNode, appendNode: AppendVNode) {
let nextOldNode: VNode | null = null; let nextOldNode: VNode | null = null;
let theLastPosition = 0;
// 从左边开始的位置 // 从左边开始的位置
let leftIdx = 0; let leftIdx = 0;
// 1. 从左侧开始比对currentVNode和newChildren若不能复用则跳出循环
for (; firstNode !== null && leftIdx < newChildren.length; leftIdx++) { function appendNode(newNode: VNode) {
if (firstNode.eIndex > leftIdx) { if (prevNewNode === null) {
// 当新旧节点位置不一,则将缓存当前的旧节点,放到下一次对比 resultingFirstChild = newNode;
nextOldNode = firstNode; newNode.cIndex = 0;
firstNode = null;
} else { } else {
nextOldNode = firstNode.next; prevNewNode.next = newNode;
newNode.cIndex = prevNewNode.cIndex + 1;
}
markVNodePath(newNode);
prevNewNode = newNode;
} }
let canBeReuse;
let newNode;
// 1. 从左侧开始比对currentVNode和newChildren若不能复用则跳出循环
for (; oldNode !== null && leftIdx < newChildren.length; leftIdx++) {
if (oldNode.eIndex > leftIdx) {
// 当新旧节点位置不一,则将缓存当前的旧节点,放到下一次对比
nextOldNode = oldNode;
oldNode = null;
} else {
nextOldNode = oldNode.next;
}
canBeReuse = checkCanReuseNode(oldNode, newChildren[leftIdx], leftIdx);
// 不能复用break // 不能复用break
if (!checkCanReuseNode(firstNode, newChildren[leftIdx], leftIdx)) { if (!canBeReuse) {
firstNode = firstNode ?? nextOldNode; oldNode = oldNode ?? nextOldNode;
break; break;
} }
const newNode = getNewNode(parentNode, newChildren[leftIdx], firstNode); newNode = getNewNode(parentNode, newChildren[leftIdx], oldNode);
// 没有生成新节点break // 没有生成新节点break
if (!newNode) { if (!newNode) {
firstNode = firstNode ?? nextOldNode; oldNode = oldNode ?? nextOldNode;
break; break;
} }
// diff过程中需要将现有的节点清除掉如果是创建则不需要处理因为没有现存节点 // diff过程中需要将现有的节点清除掉如果是创建则不需要处理因为没有现存节点
if (firstNode && newNode.isCreated) { if (oldNode && newNode.isCreated) {
deleteVNode(parentNode, firstNode); deleteVNode(parentNode, oldNode);
} }
setVNodeAdditionFlag(newNode); theLastPosition = setVNodeAdditionFlag(newNode, theLastPosition);
newNode.eIndex = leftIdx; newNode.eIndex = leftIdx;
appendNode(newNode); appendNode(newNode);
firstNode = nextOldNode; oldNode = nextOldNode;
} }
return { leftEndOldNode: firstNode, leftIdx };
}
/**
*
* @param leftEndOldNode
* @param leftIdx diff完成后Index
* @param newChildren JSX children
* @param parentNode
*/
function diffRightSide(
leftEndOldNode: VNode | null,
leftIdx: number,
newChildren: Array<any>,
parentNode: VNode
): DiffRightSideResult {
let newNode;
let canBeReuse = false;
let rightIdx = newChildren.length; let rightIdx = newChildren.length;
let rightEndOldNode; // 老节点中最右边匹配的节点引用 abcde --> abfde 则rightEndOldNode = c; let rightEndOldNode; // 老节点中最右边匹配的节点引用 abcde --> abfde 则rightEndOldNode = c;
let rightNewNode: VNode | null = null; // 最右边匹配的节点引用 abcde --> abfde 则rightNewNode = d; let rightNewNode: VNode | null = null; // 最右边匹配的节点引用 abcde --> abfde 则rightNewNode = d;
// 从后往前新资源的位置还没有到最末端旧的vNode也还没遍历完则可以考虑从后往前开始 // 从后往前新资源的位置还没有到最末端旧的vNode也还没遍历完则可以考虑从后往前开始
if (rightIdx > leftIdx && leftEndOldNode !== null) { if (rightIdx > leftIdx && oldNode !== null) {
const rightRemainingOldChildren = transRightChildrenToArray(leftEndOldNode); const rightRemainingOldChildren = transRightChildrenToArray(oldNode);
let rightOldIndex: number | null = rightRemainingOldChildren.length - 1; let rightOldIndex: number | null = rightRemainingOldChildren.length - 1;
// 2. 从右侧开始比对currentVNode和newChildren若不能复用则跳出循环 // 2. 从右侧开始比对currentVNode和newChildren若不能复用则跳出循环
@ -334,69 +333,34 @@ function diffRightSide(
deleteVNode(parentNode, rightOldNode); deleteVNode(parentNode, rightOldNode);
} }
setVNodeAdditionFlag(newNode); setVNodeAdditionFlag(newNode, theLastPosition);
newNode.eIndex = rightIdx - 1; newNode.eIndex = rightIdx - 1;
rightOldIndex--; rightOldIndex--;
rightEndOldNode = rightOldNode; rightEndOldNode = rightOldNode;
} }
} }
return { rightIdx, rightEndOldNode, rightNewNode }; // 3. 新节点已经处理完成
} if (leftIdx === rightIdx) {
/**
* Diff完成的节点
* @param leftEndOldNode
* @param parentNode
* @param firstChild VNode
* @param newChildren JSX children
* @param diffRightSideResult diff结果
* @param appendNode
*/
function appendRightSideNode(
leftEndOldNode: VNode | null,
parentNode: VNode,
firstChild: VNode | null,
newChildren: Array<any>,
diffRightSideResult: DiffRightSideResult,
appendNode: AppendVNode
) {
const { rightEndOldNode, rightNewNode } = diffRightSideResult;
// 清除中间残留的节点
if (firstChild && parentNode.tag === DomComponent && newChildren.length === 0) { if (firstChild && parentNode.tag === DomComponent && newChildren.length === 0) {
FlagUtils.markClear(parentNode); FlagUtils.markClear(parentNode);
parentNode.clearChild = firstChild; parentNode.clearChild = firstChild;
} else { } else {
deleteVNodes(parentNode, leftEndOldNode, rightEndOldNode); deleteVNodes(parentNode, oldNode, rightEndOldNode);
} }
if (rightNewNode) { if (rightNewNode) {
appendNode(rightNewNode); appendNode(rightNewNode);
setVNodesCIndex(rightNewNode, rightNewNode.cIndex + 1); setVNodesCIndex(rightNewNode, prevNewNode.cIndex + 1);
} }
}
/** return resultingFirstChild;
* }
* @param leftEndOldNode
* @param parentNode // 4. 新节点还有一部分,但是老节点已经没有了
* @param newChildren JSX children if (oldNode === null) {
* @param leftIdx diff完成后Index
* @param diffRightSideResult diff结果
* @param appendNode
*/
function appendAllRestNode(
leftEndOldNode: VNode | null,
parentNode: VNode,
newChildren: Array<any>,
leftIdx: number,
diffRightSideResult: DiffRightSideResult,
appendNode: AppendVNode
) {
let isDirectAdd = false; let isDirectAdd = false;
const { rightIdx, rightNewNode } = diffRightSideResult; // TODO: 是否可以扩大至非dom类型节点
// 如果dom节点在上次添加前没有节点说明本次添加时可以直接添加到最后不需要通过 getSiblingDom 函数找到 before 节点 // 如果dom节点在上次添加前没有节点说明本次添加时可以直接添加到最后不需要通过 getSiblingDom 函数找到 before 节点
if ( if (
parentNode.tag === DomComponent && parentNode.tag === DomComponent &&
@ -407,7 +371,7 @@ function appendAllRestNode(
} }
const isAddition = parentNode.tag === DomPortal || !parentNode.isCreated; const isAddition = parentNode.tag === DomPortal || !parentNode.isCreated;
for (; leftIdx < rightIdx; leftIdx++) { for (; leftIdx < rightIdx; leftIdx++) {
const newNode = getNewNode(parentNode, newChildren[leftIdx], null); newNode = getNewNode(parentNode, newChildren[leftIdx], null);
if (newNode !== null) { if (newNode !== null) {
if (isAddition) { if (isAddition) {
@ -425,34 +389,16 @@ function appendAllRestNode(
appendNode(rightNewNode); appendNode(rightNewNode);
setVNodesCIndex(rightNewNode.next, rightNewNode.cIndex + 1); setVNodesCIndex(rightNewNode.next, rightNewNode.cIndex + 1);
} }
}
return resultingFirstChild;
}
/** // 5. 新节点还有一部分,但是老节点也还有一部分
* LIS
* LIS的新节点直接复用
* @param leftEndOldNode
* @param parentNode
* @param newChildren JSX children
* @param leftIdx diff完成后Index
* @param diffRightSideResult diff结果
* @param appendNode
*/
function appendNodeWithLIS(
leftEndOldNode: VNode,
parentNode: VNode,
newChildren: Array<any>,
leftIdx: number,
diffRightSideResult: DiffRightSideResult,
appendNode: AppendVNode
) {
const { rightIdx, rightNewNode, rightEndOldNode } = diffRightSideResult;
// 把剩下的currentVNode转成Map // 把剩下的currentVNode转成Map
const leftChildrenMap = transLeftChildrenToMap(leftEndOldNode, rightEndOldNode); const leftChildrenMap = transLeftChildrenToMap(oldNode, rightEndOldNode);
// 通过贪心算法+二分法获取最长递增子序列 // 通过贪心算法+二分法获取最长递增子序列
const eIndexes: Array<number> = []; // 记录 eIndex 值 const eIndexes: Array<number> = []; // 记录 eIndex 值
const subsequence: Array<number> = []; // 记录最长子序列在eIndexes中的 index 值 const result: Array<number> = []; // 记录最长子序列在eIndexes中的 index 值
const preIndex: Array<number> = []; // 贪心算法在替换的过程中会使得数组不正确通过记录preIndex找到正确值 const preIndex: Array<number> = []; // 贪心算法在替换的过程中会使得数组不正确通过记录preIndex找到正确值
const reuseNodes: (VNode | null)[] = []; // 记录复用的 VNode const reuseNodes: (VNode | null)[] = []; // 记录复用的 VNode
let i = 0; let i = 0;
@ -460,7 +406,7 @@ function appendNodeWithLIS(
let last; let last;
for (; leftIdx < rightIdx; leftIdx++) { for (; leftIdx < rightIdx; leftIdx++) {
oldNodeFromMap = getOldNodeFromMap(leftChildrenMap, leftIdx, newChildren[leftIdx]); oldNodeFromMap = getOldNodeFromMap(leftChildrenMap, leftIdx, newChildren[leftIdx]);
const newNode = getNewNode(parentNode, newChildren[leftIdx], oldNodeFromMap); newNode = getNewNode(parentNode, newChildren[leftIdx], oldNodeFromMap);
if (newNode !== null) { if (newNode !== null) {
if (newNode.isCreated) { if (newNode.isCreated) {
// 新VNode直接打上标签新增不参与到复用旧的VNode会在后面打上delete标签 // 新VNode直接打上标签新增不参与到复用旧的VNode会在后面打上delete标签
@ -471,27 +417,27 @@ function appendNodeWithLIS(
if (oldNodeFromMap !== null) { if (oldNodeFromMap !== null) {
const eIndex = newNode.eIndex; const eIndex = newNode.eIndex;
eIndexes.push(eIndex); eIndexes.push(eIndex);
last = eIndexes[subsequence[subsequence.length - 1]]; last = eIndexes[result[result.length - 1]];
if (eIndex > last || last === undefined) { if (eIndex > last || last === undefined) {
// 大的 eIndex直接放在最后 // 大的 eIndex直接放在最后
preIndex[i] = subsequence[subsequence.length - 1]; preIndex[i] = result[result.length - 1];
subsequence.push(i); result.push(i);
} else { } else {
let start = 0; let start = 0;
let end = subsequence.length - 1; let end = result.length - 1;
let middle; let middle;
// 二分法找到需要替换的值 // 二分法找到需要替换的值
while (start < end) { while (start < end) {
middle = Math.floor((start + end) / 2); middle = Math.floor((start + end) / 2);
if (eIndexes[subsequence[middle]] > eIndex) { if (eIndexes[result[middle]] > eIndex) {
end = middle; end = middle;
} else { } else {
start = middle + 1; start = middle + 1;
} }
} }
if (eIndex < eIndexes[subsequence[start]]) { if (eIndex < eIndexes[result[start]]) {
preIndex[i] = subsequence[start - 1]; preIndex[i] = result[start - 1];
subsequence[start] = i; result[start] = i;
} }
} }
i++; i++;
@ -504,13 +450,13 @@ function appendNodeWithLIS(
} }
// 向前回溯找到正确的结果 // 向前回溯找到正确的结果
let length = subsequence.length; let length = result.length;
let prev = subsequence[length - 1]; let prev = result[length - 1];
while (length-- > 0) { while (length-- > 0) {
subsequence[length] = prev; result[length] = prev;
prev = preIndex[subsequence[length]]; prev = preIndex[result[length]];
} }
subsequence.forEach(idx => { result.forEach(idx => {
// 把需要复用的节点从 restNodes 中清理掉,因为不需要打 add 标记,直接复用 dom 节点 // 把需要复用的节点从 restNodes 中清理掉,因为不需要打 add 标记,直接复用 dom 节点
reuseNodes[idx] = null; reuseNodes[idx] = null;
}); });
@ -528,45 +474,7 @@ function appendNodeWithLIS(
appendNode(rightNewNode); appendNode(rightNewNode);
setVNodesCIndex(rightNewNode.next, rightNewNode.cIndex + 1); setVNodesCIndex(rightNewNode.next, rightNewNode.cIndex + 1);
} }
}
// diff数组类型的节点核心算法
function diffArrayNodesHandler(parentNode: VNode, firstChild: VNode | null, newChildren: Array<any>): VNode | null {
let resultingFirstChild: VNode | null = null;
let prevNewNode: VNode | null = null;
function appendNode(newNode: VNode) {
if (prevNewNode === null) {
resultingFirstChild = newNode;
newNode.cIndex = 0;
} else {
prevNewNode.next = newNode;
newNode.cIndex = prevNewNode.cIndex + 1;
}
markVNodePath(newNode);
prevNewNode = newNode;
}
// 1. 左端新老节点对比
const { leftEndOldNode, leftIdx } = diffLeftSide(firstChild, newChildren, parentNode, appendNode);
// 2. 右端新老节点对比
const diffRightSideResult = diffRightSide(leftEndOldNode, leftIdx, newChildren, parentNode);
// 3. 新节点已经处理完成
if (leftIdx === diffRightSideResult.rightIdx) {
appendRightSideNode(leftEndOldNode, parentNode, firstChild, newChildren, diffRightSideResult, appendNode);
return resultingFirstChild;
}
// 4. 新节点还有一部分,但是老节点已经没有了
if (leftEndOldNode === null) {
appendAllRestNode(leftEndOldNode, parentNode, newChildren, leftIdx, diffRightSideResult, appendNode);
return resultingFirstChild;
}
// 5. 新节点还有一部分,但是老节点也还有一部分
appendNodeWithLIS(leftEndOldNode, parentNode, newChildren, leftIdx, diffRightSideResult, appendNode);
return resultingFirstChild; return resultingFirstChild;
} }
@ -590,10 +498,10 @@ function diffIteratorNodesHandler(
newChildrenIterable: Iterable<any> newChildrenIterable: Iterable<any>
): VNode | null { ): VNode | null {
const iteratorFn = getIteratorFn(newChildrenIterable); const iteratorFn = getIteratorFn(newChildrenIterable);
const iteratorObj: Iterator<any> = iteratorFn.call(newChildrenIterable); const iteratorObj = iteratorFn.call(newChildrenIterable);
// 把iterator转测数组 // 把iterator转测数组
const childrenArray: any[] = []; const childrenArray = [];
let result = iteratorObj.next(); let result = iteratorObj.next();
while (!result.done) { while (!result.done) {
childrenArray.push(result.value); childrenArray.push(result.value);
@ -604,7 +512,7 @@ function diffIteratorNodesHandler(
} }
// 新节点是字符串类型 // 新节点是字符串类型
function diffStringNodeHandler(parentNode: VNode, newChild: any, firstChildVNode: VNode | null, isComparing: boolean) { function diffStringNodeHandler(parentNode: VNode, newChild: any, firstChildVNode: VNode, isComparing: boolean) {
let newTextNode: VNode | null = null; let newTextNode: VNode | null = null;
// 第一个vNode是Text则复用 // 第一个vNode是Text则复用
@ -628,7 +536,13 @@ function diffStringNodeHandler(parentNode: VNode, newChild: any, firstChildVNode
} }
// 新节点是对象类型 // 新节点是对象类型
function diffObjectNodeHandler(parentNode: VNode, firstChild: VNode | null, newChild: any, isComparing: boolean) { function diffObjectNodeHandler(
parentNode: VNode,
firstChild: VNode | null,
newChild: any,
firstChildVNode: VNode,
isComparing: boolean
) {
let canReuseNode: VNode | null = null; let canReuseNode: VNode | null = null;
// 通过key比对是否有可以reuse // 通过key比对是否有可以reuse
@ -645,7 +559,7 @@ function diffObjectNodeHandler(parentNode: VNode, firstChild: VNode | null, newC
} }
let resultNode: VNode | null = null; let resultNode: VNode | null = null;
let startDelVNode: VNode | null = firstChild; let startDelVNode = firstChildVNode;
if (newChild.vtype === TYPE_COMMON_ELEMENT) { if (newChild.vtype === TYPE_COMMON_ELEMENT) {
if (canReuseNode) { if (canReuseNode) {
// 可以复用 // 可以复用
@ -740,7 +654,7 @@ export function createChildrenByDiff(
// 5. newChild是对象类型 // 5. newChild是对象类型
if (isObjectType(newChild)) { if (isObjectType(newChild)) {
const newVNodes = diffObjectNodeHandler(parentNode, firstChild, newChild, isComparing); const newVNodes = diffObjectNodeHandler(parentNode, firstChild, newChild, firstChild, isComparing);
if (newVNodes) { if (newVNodes) {
return newVNodes; return newVNodes;
} }