Skip to content

Latest commit

 

History

History
129 lines (122 loc) · 3.19 KB

第9章.md

File metadata and controls

129 lines (122 loc) · 3.19 KB

新旧子节点前面几组 type 都相同,只有后面的有区别的 diff 算法

function patchChildren(n1, n2, container) {
  ///...
  const oldChildren = n1.children;
  const newChildren = n2.children;
  const oldLen = oldChildren.length;
  const newLen = newChildren.length;
  const commonLen = Math.min(oldLen, newLen);
  for (let i = 0; i < commonLen; i++) {
    patch(oldChildren[i], newChildren[i]);
  }
  if (newLen > oldLen) {
    patch(null, newChildren[i], container);
  } else if (newLen < oldLen) {
    for (let i = commonLen; i < oldLen; i++) {
      umount(oldChildren[i]);
    }
  }
}

通过 key 来更新

function patchChildren(n1, n2, children) {
  ///...
  const oldChildren = n1.children;
  const newChildren = n2.children;
  for (let i = 0; i < newChildren.length; i++) {
    const newVNode = oldChildren[i];
    for (let j = 0; j < oldChildren.length; j++) {
      const oldVNode = newChildren[j];
      if (newVNode.key === oldVNode.key) {
        patch(oldVNode, newVNode);
        break;
      }
    }
  }
}

// 判断是否需要移动
function patchChildren(n1, n2, children) {
  ///...
  const oldChildren = n1.children;
  const newChildren = n2.children;
  let lastIndex = 0;
  for (let i = 0; i < newChildren.length; i++) {
    const newVNode = oldChildren[i];
    for (let j = 0; j < oldChildren.length; j++) {
      const oldVNode = newChildren[j];
      if (newVNode.key === oldVNode.key) {
        patch(oldVNode, newVNode);
        if (j < lastIndex) {
          // 需要移动
        } else if (j > lastIndex) {
          lastIndex = j;
        }
        break;
      }
    }
  }
}

patchChildren

function patchChildren(n1, n2, container) {
  ///...
  if (j < lastIndex) {
    const prevVNode = newChildren[i - 1];
    if (prevVNode) {
      const anchor = prevVNode.el.nextSibling;
      insert(newVNode.el, container, anchor);
    }
  }
}
function patchChildren(n1, n2, container) {
  if (typeof n2.children === "string") {
    //
  } else if (Array.isArray(n2.children)) {
    const oldChildren = n1.children;
    const newChildren = n2.children;
    let lastIndex = 0;
    for (let i = 0; i < newChildren.length; i++) {
      const newVNode = newChildren[i];
      let j = 0;
      let find = false;
      for (; j < oldChildren; j++) {
        const oldVNode = oldChildren[j];
        const has = newChildren.find((vnode) => vnode.key === oldVNode.key);
        if (!has) {
          unmount(oldVNode);
        }
        if (j < lastIndex) {
          if (newVNode.key === oldVNode.key) {
            find = true;
            patch(oldVNode, newVNode, container);
            if (j < lastIndex) {
              const prevVNode = newChildren[j - 1];
              if (prevVNode) {
                const anchor = prevVNode.el.nextSibing;
                insert(newVNode.el, container, anchor);
              }
            }
          }
        } else {
          lastIndex = j;
        }
        break;
      }
    }
    if (!find) {
      const prevVNode = newChildren[i - 1];
      if (prevVNode) {
        const anchor = prevVNode.el.nextSibing;
      } else {
        anchor = container.firstChild;
      }
      patch(null, newVNode, container, anchor);
    }
  }
}