Match-id-42c3c229e765fde68f151e05fc0dd51b6f916989
This commit is contained in:
commit
c4d8b6de30
|
@ -353,6 +353,12 @@ function diffArrayNodes(
|
||||||
// 5. 新节点还有一部分,但是老节点也还有一部分
|
// 5. 新节点还有一部分,但是老节点也还有一部分
|
||||||
// 把剩下的currentVNode转成Map
|
// 把剩下的currentVNode转成Map
|
||||||
const leftChildrenMap = transLeftChildrenToMap(oldNode, rightEndOldNode);
|
const leftChildrenMap = transLeftChildrenToMap(oldNode, rightEndOldNode);
|
||||||
|
// 通过贪心算法+二分法获取最长递增子序列
|
||||||
|
const eIndexes = []; // 记录 eIndex 值
|
||||||
|
const result = []; // 记录最长子序列在eIndexes中的 index 值
|
||||||
|
const preIndex = []; // 贪心算法在替换的过程中会使得数组不正确,通过记录preIndex找到正确值
|
||||||
|
const reuseNodes = []; // 记录复用的 VNode
|
||||||
|
let i = 0;
|
||||||
for (; leftIdx < rightIdx; leftIdx++) {
|
for (; leftIdx < rightIdx; leftIdx++) {
|
||||||
const oldNodeFromMap = getOldNodeFromMap(leftChildrenMap, leftIdx, newChildren[leftIdx]);
|
const oldNodeFromMap = getOldNodeFromMap(leftChildrenMap, leftIdx, newChildren[leftIdx]);
|
||||||
const newNode = getNewNode(parentNode, newChildren[leftIdx], oldNodeFromMap);
|
const newNode = getNewNode(parentNode, newChildren[leftIdx], oldNodeFromMap);
|
||||||
|
@ -361,14 +367,60 @@ function diffArrayNodes(
|
||||||
// 从Map删除,后面不会deleteVNode
|
// 从Map删除,后面不会deleteVNode
|
||||||
leftChildrenMap.delete(newNode.key || leftIdx);
|
leftChildrenMap.delete(newNode.key || leftIdx);
|
||||||
}
|
}
|
||||||
|
if (oldNodeFromMap !== null) {
|
||||||
theLastPosition = setVNodeAdditionFlag(newNode, theLastPosition, isComparing);
|
let eIndex = newNode.eIndex;
|
||||||
|
eIndexes.push(eIndex);
|
||||||
|
const last = eIndexes[result[result.length - 1]];
|
||||||
|
if (eIndex > last || last === undefined) { // 大的 eIndex直接放在最后
|
||||||
|
preIndex[i] = result[result.length - 1];
|
||||||
|
result.push(i);
|
||||||
|
} else {
|
||||||
|
let start = 0;
|
||||||
|
let end = result.length - 1;
|
||||||
|
let middle;
|
||||||
|
// 二分法找到需要替换的值
|
||||||
|
while (start < end) {
|
||||||
|
middle = Math.floor((start + end) / 2)
|
||||||
|
if (eIndexes[result[middle]] > eIndex) {
|
||||||
|
end = middle;
|
||||||
|
} else {
|
||||||
|
start = middle + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (eIndex < eIndexes[result[start]]) {
|
||||||
|
preIndex[i] = result[start - 1];
|
||||||
|
result[start] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
reuseNodes.push(newNode); // 记录所有复用的节点
|
||||||
|
} else {
|
||||||
|
if (isComparing) {
|
||||||
|
FlagUtils.setAddition(newNode); // 新增节点直接打上add标签
|
||||||
|
}
|
||||||
|
}
|
||||||
newNode.eIndex = leftIdx;
|
newNode.eIndex = leftIdx;
|
||||||
appendNode(newNode);
|
appendNode(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isComparing) {
|
if (isComparing) {
|
||||||
|
// 向前回溯找到正确的结果
|
||||||
|
let length = result.length;
|
||||||
|
let prev = result[length - 1];
|
||||||
|
while (length-- > 0) {
|
||||||
|
result[length] = prev;
|
||||||
|
prev = preIndex[result[length]];
|
||||||
|
}
|
||||||
|
result.forEach(i => {
|
||||||
|
// 把需要复用的节点从 restNodes 中清理掉,因为不需要打 add 标记,直接复用 dom 节点
|
||||||
|
reuseNodes[i] = null;
|
||||||
|
});
|
||||||
|
reuseNodes.forEach(node => {
|
||||||
|
if (node !== null) {
|
||||||
|
// 没有被清理的节点打上 add 标记,通过dom的append操作实现位置移动
|
||||||
|
FlagUtils.setAddition(node);
|
||||||
|
}
|
||||||
|
});
|
||||||
leftChildrenMap.forEach(child => {
|
leftChildrenMap.forEach(child => {
|
||||||
deleteVNode(parentNode, child);
|
deleteVNode(parentNode, child);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue