深入了解虚拟DOM
虚拟DOM
什么是虚拟DOM?
是有js生成的一个DOM结构,而不是真实渲染在页面文档内的DOM,因为不是真实的DOM结构,所以叫做虚拟DOM(我们创建虚拟DOM的开销要比创建真实DOM的开销要小很多)
为什么要使用虚拟DOM?
1.手动操作dom比较麻烦,还需要考虑兼容性问题,虽然有jQuery等库能简化dom的操作,但是随着项目的复杂度dom的操作复杂度也开始提升
2.为了简化dom的简化操作,于是出现了各种mvvm框架,这个框架解决了视图和状态的同步问题
3.为了简化试图的操作,我们可以使用模板引擎,但是模版引擎没有解决状态变化的问题,于是就出现了虚拟dom
使用虚拟DOM的优点?
当前状态改变时不需要立即更新dom,只需要创建一个虚拟树来描述dom,虚拟dom内部将弄清如何有效的更新dom
参考gitHub上virtual-dom的描述:
1.虚拟dom可以维护程序的状态,跟踪上一次的状态
2.通过比较前后两次状态的差异更新真实的dom
虚拟DOM的作用?
1.维护视图和状态的关系(可以记录上次dom状态的变化,只更新状态变化的那个位置)
2.复杂视图情况下提升渲染性能
3.除了渲染dom外,还可以实现ssr(服务端渲染),原生应用,小程序等
虚拟dom开源库:
snabbdom || virtual-dom
如果在使用snabbdom引入的时候报错
Cannot resolve dependency ’snabbdom’
那是因为模块路径不是snabbdom的路径,这个路径是在作者在package,json.中的exports字段设置的,而我们的使用的打包工具不支持,所以我们需要补全路径
例:snabbdom/build/package/init.js
或者安装snabbdom@v0.7.4版本. 命令行:Yarn add snabbdom@0.7.4
snabbdom模块的使用:(snabbdom的核心库并不能处理元素的属性/样式/事件等,如需要处理的话,可以使用常用的模块[6个模块])
Attributes
设置dom元素的属性,使用setAttribute() //处理布尔类型的属性
Props
和attributes模块相似,设置dom元素的属性element[attr] = value. //不处理布尔类型的属性
Class
切换类样式。 //注意:给元素设置类样式是通过sel选择器
Dataset
设置data-*的自定义属性
eventlisteners
注册和移除事件
style
设置行内样式,支持动画 //delayed/remove/destroy
使用模块步骤:
1.导入需要使用的模块
import {h,init} from 'snabbdom';
import style from 'snabbdom/modules/style';
import eventlisteners from 'snabbdom/modules/eventlisteners';
2.在init中注册模块
let patch = init([
style,eventlisteners
]);
3.使用h()函数创建vnode的时候,可以把第二个参数设置为对象,其他参数往后移
虚拟dom进行比较方法 (patch)的过程
Patch(oldVnode,newVnode)
1.打补丁,把新节点中变化的内容渲染到真实的dom中,最后返回新节点,作为下一次处理的旧节点
2.对于新旧节点是的vnode是否相同节点(节点的key 和sel相同)
3.如果不是相同的节点,那么就删除之前的内容,重新进行渲染
4.如果是节点相同,则再判断新的vnode里是否有text,如果有且与oldvnode的text不同,则直接更新文本内容
5.如果新的vnode里有children,判断子节点是否有变化,判断的过程就使用的是diff算法
6.diff只进行同级别之间的对比
本内容不代表印象笔记立场
举报