Diff的目的是减少DOM操作的性能开销
    简单diff:

    1. if (Array.isArray(n1.children)) {
    2. //如果旧节点点是数组要进行diff
    3. const oldChildren = n1.children
    4. const newChildren = n2.children
    5. const oldLen = oldChildren.length
    6. const newLen = newChildren.length
    7. const shortLen = Math.min(oldLen, newLen)
    8. for (let i = 0; i < shortLen; i++) {
    9. //先将length较短部分进行更新
    10. patch(oldChildren[i], newChildren[i], el)
    11. }
    12. //如果旧字节点多则进行卸载
    13. if (oldLen > newLen) {
    14. for (let i = shortLen - 1; i < oldLen; i++) {
    15. unmount(oldChildren[i])
    16. }
    17. }
    18. //如果新的节点多则一一挂载
    19. if (newLen > oldLen) {
    20. for (let i = shortLen - 1; i < newLen; i++) {
    21. patch(null, newChildren[i], el)
    22. }
    23. }
    24. }

    通过key进行diff:

    1. //如果旧节点点是数组要进行diff
    2. const oldChildren = n1.children
    3. const newChildren = n2.children
    4. //有key的比较
    5. let lastIndex = 0
    6. //循环新节点
    7. for (let i = 0; i < newChildren.length; i++) {
    8. let newVNode = newChildren[i]
    9. //判断是否能找到相同key
    10. let find = false
    11. //循环旧节点
    12. for (let j = 0; j < oldChildren.length; j++) {
    13. let oldVNode = oldChildren[j]
    14. //如果两节点的key相同
    15. if (newVNode.key === oldVNode.key) {
    16. find = true
    17. patch(oldVNode, newVNode, el)
    18. //如果j小于lastIndex则需要交换位置
    19. if (j < lastIndex) {
    20. //交换位置就是将el放置到新子节点的上一个节点el后面
    21. const prevVNode = newChildren[i - 1]
    22. if (prevVNode) {
    23. const anchor = prevVNode.el.nextSibling
    24. insert(oldVNode.el, el, anchor)
    25. }
    26. } else {
    27. //否则lastIndex=j
    28. lastIndex = j
    29. }
    30. break
    31. }
    32. }
    33. //如果新字节点不能找到相同的key
    34. if (find === false) {
    35. //执行添加操作
    36. //然后将newVNode的el放置在上一节点的el后
    37. const prevVNode = newChildren[i - 1]
    38. let anchor = null
    39. if (prevVNode) {
    40. anchor = prevVNode.el.nextSibling
    41. } else {
    42. anchor = el.firstChild
    43. }
    44. patch(null, newVNode, el, anchor)
    45. }
    46. }