Diff 算法的文字性解释(vue 里其他算法性的也往这里放)
v-dom 虚拟 DOM 和 diff 算法
- v-dom 虚拟 DOM
- 通过 js 生成一个 ast 节点树/用对象模仿 dom 属性
- dom 是内容很重的数据,操作起来容易浪费性能
diff 算法
无 key 算法
- patchUnkeyedChildren 函数
- 其中有 c1 旧的 v-node 和 c2 新的 v-node 两个参数
- 第一步 遍历两个数组,新旧对比并且让新替换旧
- 第二步 发现多的节点就新增
- 第三步 发现少了就删除
有 key 算法,最长递增子序列
- patchKeyedChildren 函数
- 一样有 c1 和 c2 两个旧新节点数组
- 第一步 前序算法/先从头比较两个节点数组
- 比较使用 isSameVNodeType 函数,主要是比较 type(是不是 div 这种)和 key,都一样才返回 true
- 第二步 比较中出现不同时则跳出,进行尾序对比,从后比较两个节点数组
- 第三步 又发现不同的新节点则新增
- 第四步 发现少了相同节点旧删除/卸载
- 第五步 乱序时,比如新增删除位移同时发生,比如 input 框
- 第一步 构建新节点的映射关系
- key 是 12345,索引就是 01234,排序后 key 是 54321, 索引其实也不变, 实际上形成 key 和索引之间的 map 关系
- 第二步 新节点 在旧节点中位置 的一个数组, 有多余就删掉,不包含旧节点也删掉
- 如果节点交叉,就要用最长递增子序列做 move 是否 true 的判断
- 第三步 开始最长递增子序列的对比
- 首先进行一个贪心加二分查找结合的算法来求最长递增子序列
- 如果在子序列中就要移动节点
- 不在就跳过
vue2 的双端 diff
- 先两两从头对比
- 再两两从尾部对比
- 接着两两头对比尾
- 最后两两尾对比头
nextTick
- 将回调推迟到下一个 dom 更新周期后执行。
- 更改一些数据来等 dom 更新后马上使用
- 一个例子是每次给某个元素中加上 n 行文字,然后求此时元素高度
- 一般情况下需要 updated 钩子才能获取这个内容,一般脚本只能获取当前(未更新)的内容
- 但 update 钩子会在所有更新操作都触发,所以很多余
- nexttick 函数提供了很好的专门工具,在 dom 正式更新之后拿到数据
- 相当于 nexttick 把操作加入到微任务队列最后
- watch 这些也是用 nexttick 实现,比如一个循环加 1 一百次的函数,watch 或者 nexttick 最后都只会得到一个更新