用diff算法模擬了一個dom樹的數(shù)據(jù)結(jié)構(gòu)
vdom是樹狀結(jié)構(gòu),其節(jié)點為vnode,vnode和瀏覽器DOM中的Node一一對應(yīng),通過vnode的elm屬性可以訪問到對應(yīng)的Node。
vdom因為是純粹的JS對象,所以操作它會很高效,但是vdom的變更最終會轉(zhuǎn)換成DOM操作,為了實現(xiàn)高效的DOM操作,一套高效的虛擬DOM diff算法顯得很有必要。
vdom很好的將dom做了一層映射關(guān)系,進而將在我們本需要直接進行dom的一系列操作,映射到了操作vdom,而vdom上定義了關(guān)于真實dom的一些關(guān)鍵的信息,vdom完全是用js去實現(xiàn),和宿主瀏覽器沒有任何聯(lián)系,此外得益于js的執(zhí)行速度,將原本需要在真實dom進行的創(chuàng)建節(jié)點,刪除節(jié)點,添加節(jié)點等一系列復(fù)雜的dom操作全部放到vdom中進行,這樣就通過操作vdom來提高直接操作的dom的效率和性能。
每一個vnode都映射到一個真實的dom節(jié)點上。其中幾個比較重要的屬性:
tag 屬性即這個vnode的標簽屬性
data 屬性包含了最后渲染成真實dom節(jié)點后,節(jié)點上的class,attribute,style以及綁定的事件
children 屬性是vnode的子節(jié)點
text 屬性是文本屬性
elm 屬性為這個vnode對應(yīng)的真實dom節(jié)點
key 屬性是vnode的標記,在diff過程中可以提高diff的效率,后文有講解
比如,我定義了一個vnode,它的數(shù)據(jù)結(jié)構(gòu)是:
{
tag: 'div'
data: {
id: 'app',
class: 'page-box'
},
children: [
{
tag: 'p',
text: 'this is demo'
}
]
}
最后渲染出的實際的dom結(jié)構(gòu)就是:
<div id="app" class="page-box">
<p>this is demo</p>
</div>