对于vue虚拟dom的理解

为什么需要虚拟dom?

虚拟DOM就是为了解决浏览器性能问题而被设计出来的。例如,若一次操作中有10次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地一个JS对象中,最终将这个JS对象一次性attch到DOM树上,再进行后续操作,避免大量无谓的计算量。简单来说,可以把Virtual DOM 理解为一个简单的JS对象,并且最少包含标签名( tag)、属性(attrs)和子元素对象( children)三个属性。

实现虚拟dom

  1. 在内存中生成一颗虚拟dom树
    对于vue虚拟dom的理解
  2. 将内存中的虚拟dom树初始化渲染成真实dom树
  3. 当我们修改data里面的数据时候
    对于vue虚拟dom的理解
  4. 将之前的虚拟dom树结合新的数据生成一颗新的虚拟dom树
    对于vue虚拟dom的理解
  5. 将此次生成好的新的虚拟dom树与上一次虚拟dom树结构进行对比,对比差异(diff算法)
  6. 将对比出来的差异部分进行重新真实dom结构的渲染

diff算法的实现过程

初次渲染的时候,将VDOM渲染成真正的DOM然后插入到容器里面。
再次渲染的时候,将新的vnode和旧的vnode相对比,然后之间差异应用到所构建的真正的DOM树上。

在实际代码中,会对新旧两棵树进行一个深度的遍历,每个节点都会有一个标记。每遍历到一个节点就把该节点和新的树进行对比,如果有差异就记录到一个对象中。
渲染的一些不同改变:
1.如果节点类型改变,直接将旧节点卸载,替换为新节点,旧节点包括下面的子节点都将被卸载,如果新节点和旧节点仅仅是类型不同,但下面的所有子节点都一样时,这样做也是效率不高的一个地方。
2.节点类型不变,属性或者属性值改变,不会卸载节点,执行节点更新的操作。
3.文本改变,直接修改文字内容。
4.移动,增加,删除子节点时。
如果想在中间插入节点F,简单粗暴的做法是:卸载C,装载F,卸载D,装载C,卸载E,装载D,装载E。如下图:
对于vue虚拟dom的理解
如果为元素增加key后,Vue就能根据key,直接找到具体的位置进行操作,效率比较高。如下图:
对于vue虚拟dom的理解
在v-for中提供key,一方面可以提高性能,一方面也会避免出错。