一.虚拟 DOM (Virtual Dom)
vue2.0加入了virtual dom
1.为什么要使用虚拟DOM
- DOM很慢, 当创建一个元素比如div,有以下几项内容需要实现: HTML element、Element、GlobalEventHandler
- 简单的说,就是插入一个Dom元素的时候,这个元素上本身或者继承很多属性如 width、height、offsetHeight、style、title
- 另外还需要注册这个元素的诸多方法,比如onfucos、onclick等等
- 这还只是一个元素,如果元素比较多的时候,还涉及到嵌套,那么元素的属性和方法等等就会很多,效率很低
2.虚拟 DOM 实现原理
- 所谓的virtual dom,也就是虚拟节点
- 它通过JS的Object对象模拟DOM中的节点,然后再通过特定的render方法将其渲染成真实的DOM节点
- dom diff 则是通过JS层面的计算,返回一个patch对象,即补丁对象,在通过特定的操作解析patch对象,完成页面的重新渲染
3.虚拟 DOM 数据渲染图
4.实现步骤
- 用JavaScript对象结构表示DOM树的结构;然后用这个树构建一个真正的DOM树,插到文档当中
- 当状态变更的时候,重新构造一棵新的对象树; 然后用新的树和旧的树进行比较,记录两棵树
差异 - 把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了
5.小结
- Virtual DOM本质上就是在JS和DOM之间做了一个缓存,, 可以类比CPU和硬盘
- 既然硬盘这么慢,我们就在它们之间加个缓存; 既然DOM这么慢, 我们就在它们JS和DOM之间加个缓存
- JS(CPU)只操作Virtual DOM(内存), 最后的时候再把变更写入硬盘(DOM)
二.diff 算法
1.原理
- 比较两颗DOM数的差异是 Virtual DOM 算法中最为核心的部分,这也就是所谓的 Virtual DOM 的 diff算法
- 简单的说就是新旧虚拟DOM 的比较, 如果有差异就以新的为准, 然后再插入的真实的DOM中, 重新渲染
2.比较后出现的情况
- 两个树的完全的 diff算法 是一个时间复杂度为 O(n3) 的问题; 但是在前端中, 你会很少跨层地移动DOM元素, 所以真实的DOM算法会对同一个层级的元素进行对比
- 比较后的情况 :
1、此节点是否被移除 -> 添加新的节点
2、属性是否被改变 -> 旧属性改为新属性
3、文本内容被改变 -> 旧内容改为新内容
4、节点要被整个替换 -> 结构完全不相同,移除整个替换
三.KEY的作用
无论是vue或者react,但我们遍历数组生成dom元素的时候,都会建议我们给每一个dom元素加上key值,而且key值最好用每一项的唯一id,而不用index值(索引)
1.key 的作用
- key值的作用,其实是:追踪列表中哪些元素被添加、被修改、被移除的辅助标志
- 通俗点来说,就是他可以帮助我们快速对比两个虚拟dom对象,找到虚拟dom对象被修改的元素
- 然后仅仅替换掉被修改的元素,然后再生成新的真实dom
2.原理讲解
- 如果没有key值,就会根据就地复用的原则,一个一个对比,然后修改渲染
- 如果key值用index(索引),假如我在数组中间插入一项的时候,此时从这一项开始的key值就全部都变了,都需要重新对比渲染
- 如果有key,diff算法就可以通过对比找到正确的位置插入新节点,而key值相同的dom节点就不要去比较