虚拟dom的理解以及diff算法

发布于:2021-06-11 01:15:34

diff算法的简单理解:精细化比对,最小量更新

即新渲染出来的虚拟dom(vdom)和旧的虚拟dom进行diff(精细化比较),算出应该如何最小量更新,最后反映到真正的dom上


注意:diff算法是发生在虚拟dom上的,是新旧虚拟dom的对比。
虚拟dom的理解

用js对象来描述dom的层次结构。
注:真实dom中的一切都会在虚拟dom中有对应的属性表示。
虚拟dom的最终目标是将虚拟节点渲染到视图上。


虚拟节点的产生

h函数就是用来产生虚拟节点的(vnode),在vue中,h实际上是createElement的别名。通过此函数创建的节点是不会在页面上有所显示的,因为其创建的是虚拟节点。h函数包含以下参数:


h(标签名, 属性, 子节点)

h函数的嵌套使用可以得到虚拟dom树。因为一个h函数就可以产生一个虚拟节点。


虚拟节点通常包括以下属性:
sel(标签名)、data(属性)、children(子节点)、elm(是否显示在真实dom上)、text(标签的内容)、key(节点的唯一标识)


diff算法的注意事项

问:哪些情况下才不会进行精细化比较?
①不是同一个虚拟节点
② 跨层比较
注: 只有选择器相同且key相同才是同一个虚拟节点
以上两种情况不会进行精细化比较,而是直接删除旧的虚拟节点,然后再插入新的虚拟节点。
即只有是同一个虚拟节点,才进行精细化比较。并且,vdom只会进行同层比较,而不会进行跨层比较。


diff算法中的key

key属性是用来唯一标识节点,大白话讲就是告诉diff,它们在数据更改前后是同一个节点。
key属性一般用于以下两种场景:
一是使用v-for循环时
二是使用相同的标签名在条件渲染进行切换时


对第二点的解释:例如:运行用户在不同的登录方式间切换

上面的代码,v-if出现的span与v-else由于不可能同时出现在vdom上。这种情况下,Vue 为了尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这造成的问题是:当在填写用户账号的input时(input里面已经有值),如果用户突然忘记账号,想要换成邮箱登录,那么在切换按钮后,input里面原先输入的值,此时会原封不动地还是出现的邮箱的input中。有些情况下,这种会造成不太好的用户体验。
解决办法是,在各自的input上加上各自的key值,如:

此时,每次切换按钮时,输入框都会被重新渲染,而不是复用前面的input。


总之,vue中vdom渲染页面的过程:将模板,通过render渲染函数(h)得到虚拟的DOM树,通过diff算法进行新旧虚拟节点的比较,再通过patch更新到真实的dom上实现视图的更新。

相关推荐

最新更新

猜你喜欢