虚拟dom
是VDOM,不是VTuber
HTML文件最终都要以DOM的形式进行解析,而Virtual DOM本质上是通过JS对实际DOM进行一层抽象,因为直接操作DOM性能不够且复杂,所以把设计一种方法论,可以通过JS对象的形式描述实际DOM,进而快捷高效的操作V DOM,最后会通过特定的转换方式吧VDOM转换为实际DOM再进行更改. 比如一组实际DOM
<ul id=‘list’>
<li class=‘item’>itemA</li>
<li class=‘item’>itemB</li>
</ul>
以虚拟DOM的方式表达就是这样的:
{
tag:’ul’, // 元素的标签类型
attrs:{// 表示指定元素身上的属性
id:’list’
},
children:[ // ul元素的子节点
{
tag: ‘li’,
attrs:{
className:’item’
},
children:[‘itemA’]
}, {
tag: ‘li’,
attrs:{
className:’item’
},
children:[‘itemB’]
} ]
}
tag: 指定元素的标签类型,案例为:'ul’ (react中用type)
attrs: 表示指定元素身上的属性,如id,class, style, 自定义属性等(react中用props)
Children: 表示指定元素是否有子节点,参数以数组的形式传入,如果是文本就是数组中为字符串
VDOM的好处
首先肯定是性能优化,操作DOM非常耗时的操作,频繁的变动DOM会造成浏览器的回流重绘,所以把DOM进行抽象后,可以再patch的过程中尽可能一次性的更新DOM,保证性能
便捷,直接操作DOM必须通过相关的API不方便,而抽象后的DOM形制上其实是JS对象,可以更方便的操作,提高编码效率.
更好的跨平台性,比如Node.js就没有DOM,如果想实现SSR(服务端渲染),那么一个方式就是借助Virtual DOM,因为Virtual DOM本身是JavaScript对象. 而且在的ReactNative,React VR、weex都是使用了虚拟dom。
缺点
VDOM到实际DOM的过程实际上是需要进行一层[翻译]的,所以首次渲染大量DOM时,性能不如原生DOM,一次性插入大量DOM的情况下也不如直接innerHTML
如果你的场景是虚拟 DOM 大量更改,这是合适的。但是单一的,频繁的更新的话,虚拟 DOM 将会花费更多的时间处理计算的工作。比如,你有一个 DOM 节点相对较少页面,用虚拟 DOM,它实际上有可能会更慢。但对于大多数单页面应用,这应该都会更快。这也是为啥react和vue中的更新用了异步的方法,频繁更新时,只更新最后一次的。
虚拟DOM的实现案例
实现一套VDOM系统有三个核心问题,把大象装冰箱分三步,开冰箱,装大象,关冰箱(逃
complie:把DOM转换为VDOM
diff:通过算法,计算旧DOM结构和新DOM结构间的差异
patch:吧VDOM转换为DOM
处理属性
主要包括几类的处理
class:这里我们可以理解为动态的类名,sel上的类可以理解为静态的,例如上面class:{active:true}我们可以通过控制这个变量来表示此元素是否是当前被点击
style:内联样式
on:绑定的事件类型
dataset:data属性
hook:钩子函数
vnode = h('div#divId.red', {
'class': {
'active': true
},
'style': {
'color': 'red'
},
'on': {
'click': clickFn
}
}, [h('p', {}, '文本内容')])
function clickFn() {
console.log(click')
}
vnode = patch(app, vnode);
最后更新于