為了提高前端開發(fā)的效率,Vue提供了一種虛擬DOM的技術(shù),而虛擬DOM是通過(guò)對(duì)實(shí)際DOM的抽象來(lái)實(shí)現(xiàn)的。Vue的虛擬DOM與實(shí)際DOM保持同步,解決了DOM操作帶來(lái)的效率問(wèn)題。
虛擬DOM是一個(gè)內(nèi)存中的樹結(jié)構(gòu),可以與實(shí)際DOM結(jié)構(gòu)相對(duì)應(yīng)。在Vue中,每一個(gè)組件(包括原生組件)都有一個(gè)對(duì)應(yīng)的虛擬DOM樹。當(dāng)組件狀態(tài)發(fā)生改變時(shí),Vue會(huì)根據(jù)新的狀態(tài)重新生成一個(gè)虛擬DOM樹。然后使用虛擬DOM樹與舊的虛擬DOM樹進(jìn)行比對(duì),找出不同點(diǎn),最終只需要將不同點(diǎn)的DOM元素進(jìn)行更新。
真實(shí)DOM樹: <div id="app"> <h1>Hello World</h1> <p></p> </div> 虛擬DOM樹: { tag: 'div', attrs: { id: 'app' }, children: [ { tag: 'h1', children: 'Hello World' }, { tag: 'p' } ] }
在實(shí)際使用中,當(dāng)我們準(zhǔn)備更新頁(yè)面時(shí),首先需要將數(shù)據(jù)映射到虛擬DOM樹上,然后調(diào)用diff算法,找出新舊樹的差異。diff算法是通過(guò)深度優(yōu)先遍歷的方式,逐層比對(duì)節(jié)點(diǎn)是否相等,并給修改的節(jié)點(diǎn)打上對(duì)應(yīng)的標(biāo)記。在遍歷完整個(gè)虛擬DOM樹后,只需要處理這些標(biāo)記,并且將這些修改應(yīng)用到真實(shí)DOM樹上即可。
舊的虛擬DOM樹: { tag: 'div', attrs: { id: 'app' }, children: [ { tag: 'h1', children: 'Hello World' }, { tag: 'p' } ] } 新的虛擬DOM樹: { tag: 'div', attrs: { id: 'app' }, children: [ { tag: 'h1', children: 'Hello Vue' }, { tag: 'p' } ] } 差異: { tag: 'h1', type: 'TEXT', content: 'Hello Vue' }
上述例子中,我們將“Hello World”改為了“Hello Vue”。diff算法找到了這個(gè)變化,然后只需要將修改應(yīng)用到真實(shí)DOM上即可。
虛擬DOM在Vue中的應(yīng)用給開發(fā)者帶來(lái)了很大的便利。尤其是在大型應(yīng)用中,DOM操作會(huì)成為性能瓶頸,而虛擬DOM可以極大地減少DOM操作的數(shù)量,提高頁(yè)面渲染速度。同時(shí),虛擬DOM也提供了對(duì)跨端開發(fā)(如Web和Native)的支持,只需要重新定義與DOM相關(guān)的部分即可。