一些关于Vue diff的小小小小总结
最近有看到一些关于vue的diff算法的视频,想起我做ToDoList的时候的一些问题,就是v-for循环里key值的绑定
最先我的v-for绑定版本与它的执行结果
此时出现了一个异常尴尬的事情(不绑定key也是同一个结果)…
于是我就懵逼了…怎么这还带自己变?于是我换成了:key=“item.id"
结果十分的美好
当时还不太明白,怎么小子还有两幅面孔,后来了解到了vue的原理,了解了diff
上一个我的巨丑图:
有一个DOM元素节点,它有两个节点类型相同的子节点里面的内容分别是1和2,现在我想把1删掉(好似刚刚把dolist(未完成列表)里的li推给donelist(完成列表)=>在dolist中删除li),我们的理解是只需要删除节点1就可,但是!!虚拟DOM不是这么操作的,它找不到唯一标识key,于是选择暴力拆除和添加
在虚拟DOM中,当数据发生变化时,虚拟DOM不是立即更改真实DOM,而是通过diff算法逐级比较同一级的节点,对发生变化的节点进行更改
1.如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点以后的子节点了。
2.如果节点类型相同,则会重新设置该节点的属性,从而实现节点的更新。
所以这里,计算机认为是先将节点1的数据1=====>2,然后再删掉节点2。
所以在ToDoList里,只是更新了li里的数据,并没有更改属性,所以节点的checkbox的属性还是点击后的checked,所以,下一个被推上去的li元素被选中,而下面的不受影响。
那key绑定的id怎么就没事了呢?这就是key的作用
我们将key作为唯一的标识符去告诉diff每个节点不一样,在节点类型相同的情况下,只有key值也相等,才认为这是一个相同的节点不做更改,优化了diff。所以在第二次更改key值为li的id值以后,运行就正常了
偷来的diff图解: