Diff算法

150 阅读1分钟

优化时间复杂度到O(n)

  • 只比较同一层级,不跨级比较
  • tag不相同,则直接删掉重建,不再深度比较
  • tag和key,两者都相同,则认为是相同节点,不再深度比较

patch(oldVnode: Vnode | Element, vnode: Vnode)

  • 第一个参数不是vnode,创建一个空的vnode,关联到这个DOM元素
  • 相同的vnode(key和sel都相同),vode对比执行patchVnode()
  • 不同的vnode,直接删掉重建

patchVnode(oldVnode: Vnode, vnode: Vnode)

vnode.text === undefined

  • 新旧vnode都有children,执行updateChildren()

  • 新children有,旧children无(旧text有),清空text,添加children,执行addVnodes()

  • 旧children有,新children无,移除children

  • 旧text有,设置新text为空

    vnode.text !== undefined

  • 移除旧children,设置新text

updateChildren()

  • oldStartVnode和newStartVnode是同一个节点,对这两个节点进行patchVnode操作,如果不是同一个节点进行下一步
  • oldEndVnode和newEndVnode是同一个节点,对这两个节点进行patchVnode操作,如果不是同一个节点进行下一步
  • oldStartVnode和newEndVnode是同一个节点,对这两个节点进行patchVnode操作,如果不是同一个节点进行下一步
  • oldEndVnode和newStartVnode是同一个节点,对这两个节点进行patchVnode操作,如果不是同一个节点进行下一步
  • newStartVnode.key是否对应oldVnode.childern中的某个节点的key,如果找到,对这两个节点进行patchVnode操作,如果没有找到,创建新的节点
  • 如果是旧children先遍历完,添加新children中剩余的节点到parentElm
  • 如果是新children先遍历完,删除旧children里没被遍历的剩余节点