溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么用js對(duì)象生成dom結(jié)構(gòu)

發(fā)布時(shí)間:2022-01-05 16:15:28 來(lái)源:億速云 閱讀:346 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容介紹了“怎么用js對(duì)象生成dom結(jié)構(gòu)”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

首先咱們從起源說(shuō)起,做web開(kāi)發(fā)的時(shí)候,當(dāng)數(shù)據(jù)發(fā)生變化的時(shí)候,我們要去更新dom,從而給前端用戶呈現(xiàn)最新的數(shù)據(jù),流程圖如下:

怎么用js對(duì)象生成dom結(jié)構(gòu)

數(shù)據(jù)更改后直接操作dom,我們舉例來(lái)看一下需求,比方說(shuō)一個(gè)列表,列表下面有一個(gè)點(diǎn)擊加載更多的按鈕:

怎么用js對(duì)象生成dom結(jié)構(gòu)

點(diǎn)擊加載更多,會(huì)發(fā)送一個(gè)ajax請(qǐng)求,請(qǐng)求更多的數(shù)據(jù),然后將數(shù)據(jù)渲染到頁(yè)面,我們一般會(huì)如何做呢,代碼片段如下:

怎么用js對(duì)象生成dom結(jié)構(gòu)

我們看到,每次數(shù)據(jù)更新后,我們借助模板生成html片段,獲取列表的新舊內(nèi)容拼接,這里我們思考一下,就會(huì)發(fā)現(xiàn)已經(jīng)存在的列表信息是不應(yīng)該重新渲染的。

上面的案例先放一邊,先了解一下什么是虛擬dom,簡(jiǎn)單來(lái)說(shuō)就是一句話,用js對(duì)象來(lái)描述dom結(jié)構(gòu),示例如下:

有如下dom結(jié)構(gòu):

<ul id='list'>  <li class='item'>item1</li>  <li class='item'>item2</li></ul>

用js對(duì)象表示如下:

   {
       tag: 'ul',            attrs: {            id:'list'        },        children: [            {                tag: 'li',                attrs: {                    className: 'item'                },                children: ['item1']            }, {                tag: 'li',                attrs: {                    className: 'item'                },                children: ['item2']            }        ]    }

既然dom結(jié)構(gòu)可以表示為js對(duì)象,那么根據(jù)js對(duì)象也可以生成dom結(jié)構(gòu)。

再來(lái)看一張圖,這張圖我們將數(shù)據(jù)和ui生成一個(gè)js對(duì)象來(lái)表示dom結(jié)構(gòu)也就是Virtual Dom,然后根據(jù)這個(gè)js對(duì)象(Virtual Dom),來(lái)生成真實(shí)的Dom;

怎么用js對(duì)象生成dom結(jié)構(gòu)

虛擬dom就是上面說(shuō)的js對(duì)象,我們?cè)跀?shù)據(jù)和真實(shí)dom之間,加了一個(gè)中間層,類似夾心餅干。

這樣做有什么好處呢?我們觀察上面的流程,好像比直接操作dom還復(fù)雜,不要急,這里我們還有引入另外一個(gè)概念,diff算法,為什么要引入這個(gè)diff算法呢?

這是因?yàn)樘摂Mdom的渲染機(jī)制,那什么是虛擬dom的渲染機(jī)制呢?

當(dāng)我們更改了數(shù)據(jù)后,并不是我們想的那樣:立即成新的虛擬dom,然后根據(jù)新的虛擬dom渲染成真實(shí)Dom。而是數(shù)據(jù)更改后,在生成新的虛擬dom后,通過(guò)diff算法比較新舊虛擬dom,得出需要重新渲染的部分,然后最小化的更新真實(shí)dom。

流程如下圖:

怎么用js對(duì)象生成dom結(jié)構(gòu)

然后,我們?cè)诳瓷厦娴狞c(diǎn)擊加載更多案例,如果借助了虛擬dom,那么偽代碼可坑就是這樣操作了:

怎么用js對(duì)象生成dom結(jié)構(gòu)

虛擬dom渲染流程用代碼表示如下:

// 1. 構(gòu)建虛擬DOMvar tree = el('div', {'id': 'container'}, [    el('h2', {style: 'color: blue'}, ['simple virtal dom']),    el('p', ['Hello, virtual-dom']),    el('ul', [el('li')])])
// 2. 通過(guò)虛擬DOM構(gòu)建真正的DOMvar root = tree.render()document.body.appendChild(root)
// 3. 更改數(shù)據(jù)后生成新的虛擬DOMvar newTree = el('div', {'id': 'container'}, [    el('h2', {style: 'color: red'}, ['simple virtal dom']),    el('p', ['Hello, virtual-dom']),    el('ul', [el('li'), el('li')])])
// 4. 比較兩棵虛擬DOM樹(shù)的不同var patches = diff(tree, newTree)
// 5. 在真正的DOM元素上應(yīng)用變更patch(root, patches)

說(shuō)完虛擬dom,再次提到兩個(gè)最火的前端框架,Vue和react,這兩個(gè)框架都使用了虛擬dom,這兩個(gè)框架所使用的虛擬dom有什么不同呢?

主要是更新虛擬dom的策略不同:

vue中將數(shù)據(jù)維護(hù)成了可觀察的數(shù)據(jù),數(shù)據(jù)的每一項(xiàng)都通過(guò)getter來(lái)收集依賴,然后將依賴轉(zhuǎn)化成watcher保存在閉包中,數(shù)據(jù)修改后,觸發(fā)數(shù)據(jù)的setter方法,然后調(diào)用所有的watcher修改舊的虛擬dom,從而生成新的虛擬dom,然后就是運(yùn)用diff算法 ,得出新舊dom不同,根據(jù)不同更新真實(shí)dom。

而react的更新策略比較粗暴,可以用一個(gè)公式來(lái)表述,virtualDom = h(data),數(shù)據(jù)發(fā)生變化,通過(guò)調(diào)用setState生成新的虛擬dom,(而不是像vue一樣為每個(gè)數(shù)據(jù)社會(huì)setter、getter、watcher),然后對(duì)比新舊dom,得出新舊dom不同,更新真實(shí)dom。但是,react給開(kāi)發(fā)者暴露一個(gè)生命周期函數(shù):shouldcomponentupdate,這個(gè)函數(shù)可以根據(jù)開(kāi)發(fā)者的需求決定數(shù)據(jù)發(fā)生變化決定是否重新渲染。

react是 函數(shù)式組件思想,當(dāng)你 setstate 就會(huì)遍歷,diff 當(dāng)前組件所有的子節(jié)點(diǎn)子組件, 這種方式開(kāi)銷是很大的,要合理使用shouldcomponentupdate。

vue為每個(gè)數(shù)據(jù)設(shè)置setter、getter、watcher,當(dāng)數(shù)據(jù)足夠多時(shí),運(yùn)行效率反倒不如react。

所以在選擇框架時(shí),要衡量一下,如果頁(yè)面數(shù)據(jù)量大,變化多,選react,而如果項(xiàng)目中型,并且想快速開(kāi)發(fā),選vue。

“怎么用js對(duì)象生成dom結(jié)構(gòu)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI