vue中的虚拟dom和diff算法

312 阅读2分钟

虚拟dom

虚拟dom其实就是数据 虚拟dom和真实节点

  • 虚拟dom
{
    children: [{…}],
    data: {},
    elm: h1,
    key: undefined,
    sel: "h1",
    text: undefined
}
  • 真实节点
<h2>我是h2</h2>

diff算法

diff算法的核心其实就是dom数据化,提升性能, 生成的虚拟dom跟真实的节点进行比较,然后进行更新

  • 比较规则
    • 如果新旧节点不是同一个节点,那么会直接添加新节点,然后删除旧节点(比如旧节点是div,新节点是h1,那么会先创建h1,然后再删除div)
    • 只能进行同级比较,不能跨级比较(比如div和ul是同级的,只能div和ul进行比较,而不能使用ul中li跟div进行比较)
    • 如果新旧节点是同一个节点
      • 新节点没有children,那么就说明新节点是文本,不管旧节点有没有children,都会被新节点的文本直接覆盖
      • 新节点有children,旧节点没有children,那么会清空旧节点的内容,然后添加新节点的children
      • 新节点有children,旧节点也有children ===> diff算法的核心
  • diff算法的核心
    • 旧前 和 新前,指针都++
      • 内容进行patch
    • 旧后 和 新后,指针都--
      • 内容进行patch
    • 旧前 和 新后,旧前指针++、新后指针--
      • 内容进行patch,旧前子节点移动到旧节点的最后一个节点(后移动过去的节点不算,是原来旧节点的最后一个子节点)
    • 旧后 和 新前,旧后指针--、新前指针++
      • 内容进行patch,旧后子节点移动到旧节点的第一个节点的最前(后移动过去的节点不算,是原来旧节点的第一个子节点)
    • 都不满足
      • 拿新前子节点去旧节点中进行查找
        • 如果找不到,就直接创建,插入到旧节点的最前
        • 如果找到了,把旧节点中找到的子节点移动到旧节点的最前,然后把原来子节点的位置设置为undefined
    • 删除或创建 指针++或--的时候,如果遇到 undefined,那么会跳过,往下一个找