虚拟DOM和diff算法(四) diff算法 更新节点

251 阅读1分钟

新旧节点对比

1.新节点和旧节点在内存中就算一个节点(什么都不做) 2.判断新节点有text属性,并且没有children.

再判断新旧节点text值是否一致(不一致则直接覆盖旧节点值)

3.新节点没有text属性

判断旧节点有没有子节点children(没有子节点children,不用精细化比较,直接清空。将新节点插入旧节点) 旧节点有子节点(命中算法,精细化更新updateElement)


import createElement from "./createElement.js"
import updateElement from "./updateElement.js"
// 对比同一个虚拟节点
export default function (oldVnode, newVnode) {
  // 内存中是同一个节点,返回
  if (oldVnode === newVnode) {
    console.log('内存中是同一个节点,返回')
    return
  }
  // 判断新节点有text 并且 没有children
  if (newVnode.text != undefined && (newVnode.children == undefined || newVnode.children.length == 0)) {
    // 新节点有text属性
    console.log('新节点有text属性')
    // 如果新旧节点text属性不一致
    if (newVnode.text != oldVnode.text) {
      oldVnode.elm.innerText = newVnode.text
    }
  } else {
    console.log('新节点没有text属性')
    // 旧节点有children
    if (oldVnode.children != undefined && oldVnode.children.length > 0) {
      // 最复杂情况
       // 老的有children,新的也有children,此时就是最复杂的情况。
       updateElement(oldVnode.elm, oldVnode.children, newVnode.children)
    } else {
      // 旧节点没有children不用精细化比较,直接清空。将新节点插入旧节点
      // 清空旧节点
      oldVnode.elm.innerHTML = ''
      // 遍历新节点子节点
      let i = 0
      while (i <= newVnode.children.length - 1 ) {
        let dom = createElement(newVnode.children[i])
        oldVnode.elm.appendChild(dom);
        i++
      }
    }
  }
}