虚拟DOM
优点: 减少DOM操作,虚拟DOM 可以将多次操作合并为一次操作,比如添加1000个节点,却是一个接一个操作的(减少频率) 虚拟DOM借助 DOM diff 可以把多余的操作声调,比如你操作1000个节点,其实只有10个新增的.
跨平台: 虚拟DOM 不仅可以变成DOM,还可以变成小程序、ISO应用、安卓应用、因为虚拟DOM本质上只是一个JS对象
缺点: 需要额外的创建函数。如createElement或 h, 但是可以通过JSX 来简写成 XML
// 如何创建虚拟DOM
Vue Template
<div class="red" @click="fn">
<span>string1</span>
<span>string2</span>
</div>
// 通过 vue-loader 转为 h形式
const vNode = {
tag: 'div' // 标签名 or 组件名
data:{
class: 'red', //标签上的属性
on: {
click: ()=>{} // 事件
}
},
childred:[ // 子元素
{tag: 'span','....'}
{tag: 'span','....'}
]
}
// vue 只能在render 函数里获取得到h
h('div',{
class: 'red',
on:{
cilck: ()=>{}
}
})
// React
const vNode ={
key:null,
props:{
childred: [//子元素
{type:'span',...},
{type:'span',...}
],
className: 'red', // 标签上的属性
onclick: ()=>{} // 事件
},
ref:null,
type: 'div' // 标签名 or 组件名
}
<div className="red" onclick="()=>{}">
<span>span1</span>
<span>span2</span>
</div>
通过 babel 转为createElement 形式
createElement('div',{
className:'red',
},
[
createElement('span',{},'span1'),
createElement('span',{},'span2')
])
DOM diff
什么是 DOM diff 就是一个函数,我们成为 patch.
patches = patch(oldVNode,newVNode)
patches就是要运行的DOM 操作。
DOM diff 大概逻辑是
将新旧两棵树进行逐层对比,找出哪些节点需要更新,如果节点是组件,就看Component diff. 如果是组件就先看组件的类型,类型不同直接替换,删除旧的,类型相同就直接更新,然后在深入组件进行对比。 如果节点是原生标签,就看标签名,标签名不同直接替换,如果相同就看属性,属性相同就更新属性。
DOM diff 的优点 :
可以做到只把变化的部分重新渲染,提高渲染效率的过程。
DOM diff 的缺点
同级节点对比会存在BUG。
给每个节点起个名字 ID,ID 可以是数字,字符串,能代表它是谁即可