vue虛擬DOM和render()函數(shù)詳解
vue虛擬DOM和render()函數(shù)
與其他的前端開發(fā)框架相比,Vue.js的優(yōu)勢(shì)是執(zhí)行性能比較高,這里有一個(gè)很重要的原因就是Vue.js采用虛擬DOM機(jī)制。
雖然大多數(shù)情況下,Vue.js推薦使用模板構(gòu)建HTML,但是在某些場(chǎng)景下,可能需要JavaScript的編程能力,這時(shí)就需要使用render()函數(shù),它比模板更接近編輯器。
通過本章內(nèi)容的學(xué)習(xí),讀者可以了解虛擬DOM和render()函數(shù)的使用方法。
虛擬DOM
DOM即文檔對(duì)象模型,它提供了對(duì)整個(gè)文檔的訪問模型,將文檔作為一個(gè)樹形結(jié)構(gòu),樹的每個(gè)結(jié)點(diǎn)表示了一個(gè)HTML標(biāo)簽或標(biāo)簽內(nèi)的文本項(xiàng)。
DOM樹結(jié)構(gòu)精確地描述了HTML文檔中標(biāo)簽間的相互關(guān)聯(lián)性。瀏覽器在解析HTML文檔時(shí),會(huì)將文檔中的元素、注釋、文本等標(biāo)記按照它們的層級(jí)關(guān)系轉(zhuǎn)化為DOM樹。
一個(gè)元素要想在頁面中顯示,則必須在DOM中存在該節(jié)點(diǎn),也就是必須將該元素節(jié)點(diǎn)添加到現(xiàn)有DOM樹中的某個(gè)節(jié)點(diǎn)下,才能渲染到頁面中。同樣地,如果需要?jiǎng)h除某個(gè)元素,也需要從DOM樹中刪除該元素對(duì)應(yīng)的節(jié)點(diǎn)。
如果每次要改變頁面展示的內(nèi)容,只能通過遍歷查詢DOM樹,然后修改DOM樹,從而達(dá)到更新頁面的目的,這個(gè)過程相當(dāng)消耗資源。
為了解決這個(gè)問題,虛擬DOM概念隨著React的誕生而誕生,其由Facebook提出,其卓越的性能很快得到廣大開發(fā)者的認(rèn)可。因?yàn)槊看尾樵僁OM幾乎都需要遍歷整個(gè)DOM樹,如果建立一個(gè)與DOM樹對(duì)應(yīng)的虛擬DOM對(duì)象,也就是JavaScript對(duì)象,以對(duì)象嵌套的方式來表示DOM樹及其層級(jí)結(jié)構(gòu),那么每次DOM的修改就變成了對(duì)JavaScript對(duì)象的屬性的操作,由于操作JavaScript對(duì)象比操作DOM要快得多,從而大幅度減少性能的開支。
Vue從2.0開始也在其核心引入了虛擬DOM的概念,Vue.js 3.x重寫了虛擬DOM的實(shí)現(xiàn),從而讓性能更加優(yōu)秀。
Vue在更新真實(shí)的DOM樹之前,先比較更新前后虛擬DOM結(jié)構(gòu)中有差異的部分,然后采用異步更新隊(duì)列的方式將差異部分更新到真實(shí)DOM中,從而減少了最終要在真實(shí)DOM上執(zhí)行的操作次數(shù),提高了頁面的渲染效率。
render()函數(shù)
大多數(shù)情況下,Vue通過template來創(chuàng)建HTML。但是在特殊情況下,可能需要JavaScript的編程能力,這時(shí)可以使用render()函數(shù),它比模板更接近編譯器。
下面通過一個(gè)簡(jiǎn)單的例子,了解render()函數(shù)的優(yōu)勢(shì)。假設(shè)需要生成一些帶錨點(diǎn)的標(biāo)題,基礎(chǔ)代碼如下:
<h1>
<a name="hello-world" href="#hello-world" rel="external nofollow" rel="external nofollow" >
Hello world!
</a>
</h1>由于錨點(diǎn)標(biāo)題的使用非常頻繁,考慮到標(biāo)題的級(jí)別包括h1~h6,可以將標(biāo)題的級(jí)別定義成組件的prop,在調(diào)用組件時(shí),可以通過該prop動(dòng)態(tài)設(shè)置標(biāo)題元素的級(jí)別。
代碼如下:
<anchored-heading :level="1">Hello world!</anchored-heading>
接下來就是組件的實(shí)現(xiàn)代碼:
const app = createApp({})
app.component(‘a(chǎn)nchored-heading', {
template: `
props: { level: { type: Number, required: true } } })上述通過模板的方式實(shí)現(xiàn)起來不僅冗長(zhǎng),而且為每個(gè)級(jí)別標(biāo)題都重復(fù)書寫了。
當(dāng)添加錨元素時(shí),還必須在每個(gè) v-if/v-else-if 分支中再次復(fù)制元素。
<div id="app">
<anchored-heading :level="2">
<a name="hello-world" href="#hello-world" rel="external nofollow" rel="external nofollow" >
相顧無相識(shí),長(zhǎng)歌懷采薇。
</a>
</anchored-heading>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({})
app.component('anchored-heading', {
render() {
const { h } = Vue
return h(
'h' + this.level, // 標(biāo)簽名
{}, // prop 或 attribute
this.$slots.default() // 包含其子節(jié)點(diǎn)的數(shù)組
)
},
props: {
level: {
type: Number,
required: true
}
})
app.mount('#app')
</script>可見使用render()函數(shù)的實(shí)現(xiàn)要精簡(jiǎn)得多。
需要注意的是:
向組件中傳遞不帶v-slot指令的子節(jié)點(diǎn)時(shí),比如 anchored-heading 中的 Hello world!,這些子節(jié)點(diǎn)被存儲(chǔ)在組件實(shí)例中的$slots.default中。在谷歌瀏覽器中運(yùn)行程序。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue+elementui(對(duì)話框中form表單的reset問題)
這篇文章主要介紹了vue+elementui(對(duì)話框中form表單的reset問題),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
基于Vue.js 2.0實(shí)現(xiàn)百度搜索框效果
這篇文章主要為大家詳細(xì)介紹了基于Vue.js 2.0實(shí)現(xiàn)百度搜索框效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
解決VUE-Router 同一頁面第二次進(jìn)入不刷新的問題
這篇文章主要介紹了解決VUE-Router 同一頁面第二次進(jìn)入不刷新的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07
vue3中利用Export2Excel將數(shù)據(jù)導(dǎo)出為excel表格
這篇文章主要給大家介紹了關(guān)于vue3中利用Export2Excel將數(shù)據(jù)導(dǎo)出為excel表格的相關(guān)資料,最近項(xiàng)目需要前端來導(dǎo)出Excel操作,所以給大家總結(jié)下,需要的朋友可以參考下2023-09-09
vue-loader中引入模板預(yù)處理器的實(shí)現(xiàn)
這篇文章主要介紹了vue-loader中引入模板預(yù)處理器的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
在vue中實(shí)現(xiàn)echarts隨窗體變化
這篇文章主要介紹了在vue中實(shí)現(xiàn)echarts隨窗體變化,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07

