共计 1372 个字符,预计需要花费 4 分钟才能阅读完成。
一. 虚拟 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 节点就不要去比较
正文完