vue的虚拟dom与diff算法借鉴了snabbdom
虚拟dom:
用javascript对象描述DOM的层次结构。DOM中一切属性都在虚拟DOM中有对应的属性。
真实DOM
<div class="box">
<h3>我是一个标题</h3>
<ul>
<li>牛奶</li>
<li>咖啡</li>
<li>可乐</li>
</ul>
</div>
虚拟DOM
{
'sel':"div",
"data":{
"class":{
"box":true
}
},
"children":[
{
'sel':"h3",
"data":{},
"text":"我是一个标题"
},
{
'sel':"ul",
"data":{},
"children":[
{"sel":"li",'data':{},"text":"牛奶"},
{"sel":"li",'data':{},"text":"咖啡"},
{"sel":"li",'data':{},"text":"可乐"},
]
}
]
}
diff是发生在虚拟DOM上的
新虚拟DOM和老虚拟DOM进行diff(精细化比较),算出应该如何最小量更新,最后反映到真正的DOM上。
完整的虚拟节点
{
children:undefined,
data:{},
elm:undefined,
key:undefined,
sel:‘div’,
text:‘我是一个盒子’
}
h函数可以嵌套使用,从而得到DOM树(重要)
比如这样嵌入使用h函数:
h(‘ul’,{}[
h(‘li’,{},‘牛奶’),
h(‘li’,{},‘咖啡’),
h(‘li’,{},‘可乐’),
]);
将得到这样的虚拟DOM树:
{
“sel”:“ul”,
“data”:{},
“children”:[
{“sel”:“li”,“text”:“牛奶”},
{“sel”:“li”,“text”:“咖啡”},
{“sel”:“li”,“text”:“可乐”},
]
}
diff处理逻辑
key很重要,key是这个节点的唯一标识,告诉diff算法,在更改前后他们是同一个DOM节点
只有是同一个虚拟节点,才进行精细化比较,否则就是暴力删除旧的,插入新的。选择器相同且key相同才是同一个虚拟节点。
只进行同层比较,不会进行跨层比较。即使是同一片虚拟节点,但是跨层了,对不起。精细化比较不diff你,而是暴力删除旧的,然后插入新的。
