Match-id-537885abef3b19db381ea7c2a867b17d0fc561c4

This commit is contained in:
* 2022-04-15 14:26:56 +08:00 committed by *
commit 496f0fe0b4
3 changed files with 67 additions and 78 deletions

View File

@ -62,11 +62,11 @@ export function FilterTree<T extends BaseType>(props: { data: T[] }) {
const collapsedNodes = collapsedNodesRef.current; const collapsedNodes = collapsedNodesRef.current;
const updateCollapsedNodes = (item: BaseType) => { const updateCollapsedNodes = (item: BaseType) => {
const newcollapsedNodes = expandItemParent(item, data, collapsedNodes); const newCollapsedNodes = expandItemParent(item, data, collapsedNodes);
// 如果新旧收起节点数组长度不一样,说明存在收起节点 // 如果新旧收起节点数组长度不一样,说明存在收起节点
if (newcollapsedNodes.length !== collapsedNodes.length) { if (newCollapsedNodes.length !== collapsedNodes.length) {
// 更新引用,确保 VTree 拿到新的 collapsedNodes // 更新引用,确保 VTree 拿到新的 collapsedNodes
collapsedNodesRef.current = newcollapsedNodes; collapsedNodesRef.current = newCollapsedNodes;
} }
}; };

View File

@ -5,7 +5,7 @@ import ComponentInfo from '../components/ComponentInfo';
import styles from './App.less'; import styles from './App.less';
import Select from '../svgs/Select'; import Select from '../svgs/Select';
import { mockParsedVNodeData, parsedMockState } from '../devtools/mock'; import { mockParsedVNodeData, parsedMockState } from '../devtools/mock';
import { FilterTree } from '../components/FilterTree'; import { FilterTree } from '../hooks/FilterTree';
import Close from '../svgs/Close'; import Close from '../svgs/Close';
import Arrow from './../svgs/Arrow'; import Arrow from './../svgs/Arrow';

View File

@ -96,11 +96,8 @@ function getNodeType(newChild: any): string | null {
} }
// 设置vNode的flag // 设置vNode的flag
function setVNodeAdditionFlag(newNode: VNode, lastPosition: number, isComparing: boolean): number { function setVNodeAdditionFlag(newNode: VNode, lastPosition: number): number {
let position = lastPosition; let position = lastPosition;
if (!isComparing) {
return position;
}
if (newNode.isCreated || newNode.eIndex < lastPosition) { // 位置 小于 上一个复用的位置 if (newNode.isCreated || newNode.eIndex < lastPosition) { // 位置 小于 上一个复用的位置
// 标记为新增 // 标记为新增
@ -221,7 +218,6 @@ function diffArrayNodesHandler(
parentNode: VNode, parentNode: VNode,
firstChild: VNode | null, firstChild: VNode | null,
newChildren: Array<any>, newChildren: Array<any>,
isComparing: boolean
): VNode | null { ): VNode | null {
let resultingFirstChild: VNode | null = null; let resultingFirstChild: VNode | null = null;
@ -273,11 +269,11 @@ function diffArrayNodesHandler(
} }
// diff过程中需要将现有的节点清除掉如果是创建则不需要处理因为没有现存节点 // diff过程中需要将现有的节点清除掉如果是创建则不需要处理因为没有现存节点
if (isComparing && oldNode && newNode.isCreated) { if (oldNode && newNode.isCreated) {
deleteVNode(parentNode, oldNode); deleteVNode(parentNode, oldNode);
} }
theLastPosition = setVNodeAdditionFlag(newNode, theLastPosition, isComparing); theLastPosition = setVNodeAdditionFlag(newNode, theLastPosition);
newNode.eIndex = leftIdx; newNode.eIndex = leftIdx;
appendNode(newNode); appendNode(newNode);
oldNode = nextOldNode; oldNode = nextOldNode;
@ -319,11 +315,11 @@ function diffArrayNodesHandler(
rightNewNode = newNode; rightNewNode = newNode;
} }
if (isComparing && rightOldNode && newNode.isCreated) { if (rightOldNode && newNode.isCreated) {
deleteVNode(parentNode, rightOldNode); deleteVNode(parentNode, rightOldNode);
} }
setVNodeAdditionFlag(newNode, theLastPosition, isComparing); setVNodeAdditionFlag(newNode, theLastPosition);
newNode.eIndex = rightIdx - 1; newNode.eIndex = rightIdx - 1;
rightOldIndex--; rightOldIndex--;
rightEndOldNode = rightOldNode; rightEndOldNode = rightOldNode;
@ -332,13 +328,11 @@ function diffArrayNodesHandler(
// 3. 新节点已经处理完成 // 3. 新节点已经处理完成
if (leftIdx === rightIdx) { if (leftIdx === rightIdx) {
if (isComparing) { 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, oldNode, rightEndOldNode);
deleteVNodes(parentNode, oldNode, rightEndOldNode);
}
} }
if (rightNewNode) { if (rightNewNode) {
@ -360,11 +354,12 @@ function diffArrayNodesHandler(
rightIdx - leftIdx === newChildren.length) { rightIdx - leftIdx === newChildren.length) {
isDirectAdd = true; isDirectAdd = true;
} }
const isAddition = parentNode.tag === DomPortal || !parentNode.isCreated;
for (; leftIdx < rightIdx; leftIdx++) { for (; leftIdx < rightIdx; leftIdx++) {
newNode = getNewNode(parentNode, newChildren[leftIdx], null); newNode = getNewNode(parentNode, newChildren[leftIdx], null);
if (newNode !== null) { if (newNode !== null) {
if (isComparing) { if (isAddition) {
FlagUtils.setAddition(newNode); FlagUtils.setAddition(newNode);
} }
if (isDirectAdd) { if (isDirectAdd) {
@ -398,42 +393,39 @@ function diffArrayNodesHandler(
oldNodeFromMap = getOldNodeFromMap(leftChildrenMap, leftIdx, newChildren[leftIdx]); oldNodeFromMap = getOldNodeFromMap(leftChildrenMap, leftIdx, newChildren[leftIdx]);
newNode = getNewNode(parentNode, newChildren[leftIdx], oldNodeFromMap); newNode = getNewNode(parentNode, newChildren[leftIdx], oldNodeFromMap);
if (newNode !== null) { if (newNode !== null) {
if (isComparing && !newNode.isCreated) {
// 从Map删除后面不会deleteVNode
leftChildrenMap.delete(newNode.key || leftIdx);
}
if (newNode.isCreated) { if (newNode.isCreated) {
// 新VNode直接打上标签新增不参与到复用旧的VNode会在后面打上delete标签
FlagUtils.setAddition(newNode); FlagUtils.setAddition(newNode);
} else if (oldNodeFromMap !== null) { } else {
const eIndex = newNode.eIndex; // 从Map删除后面不会deleteVNode就可以实现复用
eIndexes.push(eIndex); leftChildrenMap.delete(newNode.key || leftIdx);
last = eIndexes[result[result.length - 1]]; if (oldNodeFromMap !== null) {
if (eIndex > last || last === undefined) { // 大的 eIndex直接放在最后 const eIndex = newNode.eIndex;
preIndex[i] = result[result.length - 1]; eIndexes.push(eIndex);
result.push(i); last = eIndexes[result[result.length - 1]];
} else { if (eIndex > last || last === undefined) { // 大的 eIndex直接放在最后
let start = 0; preIndex[i] = result[result.length - 1];
let end = result.length - 1; result.push(i);
let middle; } else {
// 二分法找到需要替换的值 let start = 0;
while (start < end) { let end = result.length - 1;
middle = Math.floor((start + end) / 2); let middle;
if (eIndexes[result[middle]] > eIndex) { // 二分法找到需要替换的值
end = middle; while (start < end) {
} else { middle = Math.floor((start + end) / 2);
start = middle + 1; if (eIndexes[result[middle]] > eIndex) {
end = middle;
} else {
start = middle + 1;
}
}
if (eIndex < eIndexes[result[start]]) {
preIndex[i] = result[start - 1];
result[start] = i;
} }
} }
if (eIndex < eIndexes[result[start]]) { i++;
preIndex[i] = result[start - 1]; reuseNodes.push(newNode); // 记录所有复用的节点
result[start] = i;
}
}
i++;
reuseNodes.push(newNode); // 记录所有复用的节点
} else {
if (isComparing) {
FlagUtils.setAddition(newNode); // 新增节点直接打上add标签
} }
} }
newNode.eIndex = leftIdx; newNode.eIndex = leftIdx;
@ -441,28 +433,26 @@ function diffArrayNodesHandler(
} }
} }
if (isComparing) { // 向前回溯找到正确的结果
// 向前回溯找到正确的结果 let length = result.length;
let length = result.length; let prev = result[length - 1];
let prev = result[length - 1]; while (length-- > 0) {
while (length-- > 0) { result[length] = prev;
result[length] = prev; prev = preIndex[result[length]];
prev = preIndex[result[length]];
}
result.forEach(idx => {
// 把需要复用的节点从 restNodes 中清理掉,因为不需要打 add 标记,直接复用 dom 节点
reuseNodes[idx] = null;
});
reuseNodes.forEach(node => {
if (node !== null) {
// 没有被清理的节点打上 add 标记通过dom的append操作实现位置移动
FlagUtils.setAddition(node);
}
});
leftChildrenMap.forEach(child => {
deleteVNode(parentNode, child);
});
} }
result.forEach(idx => {
// 把需要复用的节点从 restNodes 中清理掉,因为不需要打 add 标记,直接复用 dom 节点
reuseNodes[idx] = null;
});
reuseNodes.forEach(node => {
if (node !== null) {
// 没有被清理的节点打上 add 标记通过dom的append操作实现位置移动
FlagUtils.setAddition(node);
}
});
leftChildrenMap.forEach(child => {
deleteVNode(parentNode, child);
});
if (rightNewNode) { if (rightNewNode) {
appendNode(rightNewNode); appendNode(rightNewNode);
@ -490,7 +480,6 @@ function diffIteratorNodesHandler(
parentNode: VNode, parentNode: VNode,
firstChild: VNode | null, firstChild: VNode | null,
newChildrenIterable: Iterable<any>, newChildrenIterable: Iterable<any>,
isComparing: boolean
): VNode | null { ): VNode | null {
const iteratorFn = getIteratorFn(newChildrenIterable); const iteratorFn = getIteratorFn(newChildrenIterable);
const iteratorObj = iteratorFn.call(newChildrenIterable); const iteratorObj = iteratorFn.call(newChildrenIterable);
@ -503,7 +492,7 @@ function diffIteratorNodesHandler(
result = iteratorObj.next(); result = iteratorObj.next();
} }
return diffArrayNodesHandler(parentNode, firstChild, childrenArray, isComparing); return diffArrayNodesHandler(parentNode, firstChild, childrenArray);
} }
// 新节点是字符串类型 // 新节点是字符串类型
@ -644,12 +633,12 @@ export function createChildrenByDiff(
// 3. newChild是数组类型 // 3. newChild是数组类型
if (Array.isArray(newChild)) { if (Array.isArray(newChild)) {
return diffArrayNodesHandler(parentNode, firstChild, newChild, isComparing); return diffArrayNodesHandler(parentNode, firstChild, newChild);
} }
// 4. newChild是迭代器类型 // 4. newChild是迭代器类型
if (isIteratorType(newChild)) { if (isIteratorType(newChild)) {
return diffIteratorNodesHandler(parentNode, firstChild, newChild, isComparing); return diffIteratorNodesHandler(parentNode, firstChild, newChild);
} }
// 5. newChild是对象类型 // 5. newChild是对象类型