本篇內(nèi)容介紹了“怎么用js對象生成dom結(jié)構(gòu)”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)建站是專業(yè)的余干網(wǎng)站建設(shè)公司,余干接單;提供網(wǎng)站建設(shè)、網(wǎng)站制作,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行余干網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
首先咱們從起源說起,做web開發(fā)的時候,當(dāng)數(shù)據(jù)發(fā)生變化的時候,我們要去更新dom,從而給前端用戶呈現(xiàn)最新的數(shù)據(jù),流程圖如下:
數(shù)據(jù)更改后直接操作dom,我們舉例來看一下需求,比方說一個列表,列表下面有一個點擊加載更多的按鈕:
點擊加載更多,會發(fā)送一個ajax請求,請求更多的數(shù)據(jù),然后將數(shù)據(jù)渲染到頁面,我們一般會如何做呢,代碼片段如下:
我們看到,每次數(shù)據(jù)更新后,我們借助模板生成html片段,獲取列表的新舊內(nèi)容拼接,這里我們思考一下,就會發(fā)現(xiàn)已經(jīng)存在的列表信息是不應(yīng)該重新渲染的。
上面的案例先放一邊,先了解一下什么是虛擬dom,簡單來說就是一句話,用js對象來描述dom結(jié)構(gòu),示例如下:
有如下dom結(jié)構(gòu):
用js對象表示如下:
{
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對象,那么根據(jù)js對象也可以生成dom結(jié)構(gòu)。
再來看一張圖,這張圖我們將數(shù)據(jù)和ui生成一個js對象來表示dom結(jié)構(gòu)也就是Virtual Dom,然后根據(jù)這個js對象(Virtual Dom),來生成真實的Dom;
虛擬dom就是上面說的js對象,我們在數(shù)據(jù)和真實dom之間,加了一個中間層,類似夾心餅干。
這樣做有什么好處呢?我們觀察上面的流程,好像比直接操作dom還復(fù)雜,不要急,這里我們還有引入另外一個概念,diff算法,為什么要引入這個diff算法呢?
這是因為虛擬dom的渲染機制,那什么是虛擬dom的渲染機制呢?
當(dāng)我們更改了數(shù)據(jù)后,并不是我們想的那樣:立即成新的虛擬dom,然后根據(jù)新的虛擬dom渲染成真實Dom。而是數(shù)據(jù)更改后,在生成新的虛擬dom后,通過diff算法比較新舊虛擬dom,得出需要重新渲染的部分,然后最小化的更新真實dom。
流程如下圖:
然后,我們在看上面的點擊加載更多案例,如果借助了虛擬dom,那么偽代碼可坑就是這樣操作了:
虛擬dom渲染流程用代碼表示如下:
// 1. 構(gòu)建虛擬DOM
var tree = el('div', {'id': 'container'}, [
el('h2', {style: 'color: blue'}, ['simple virtal dom']),
el('p', ['Hello, virtual-dom']),
el('ul', [el('li')])
])
// 2. 通過虛擬DOM構(gòu)建真正的DOM
var root = tree.render()
document.body.appendChild(root)
// 3. 更改數(shù)據(jù)后生成新的虛擬DOM
var 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樹的不同
var patches = diff(tree, newTree)
// 5. 在真正的DOM元素上應(yīng)用變更
patch(root, patches)
說完虛擬dom,再次提到兩個最火的前端框架,Vue和react,這兩個框架都使用了虛擬dom,這兩個框架所使用的虛擬dom有什么不同呢?
主要是更新虛擬dom的策略不同:
vue中將數(shù)據(jù)維護成了可觀察的數(shù)據(jù),數(shù)據(jù)的每一項都通過getter來收集依賴,然后將依賴轉(zhuǎn)化成watcher保存在閉包中,數(shù)據(jù)修改后,觸發(fā)數(shù)據(jù)的setter方法,然后調(diào)用所有的watcher修改舊的虛擬dom,從而生成新的虛擬dom,然后就是運用diff算法 ,得出新舊dom不同,根據(jù)不同更新真實dom。
而react的更新策略比較粗暴,可以用一個公式來表述,virtualDom = h(data),數(shù)據(jù)發(fā)生變化,通過調(diào)用setState生成新的虛擬dom,(而不是像vue一樣為每個數(shù)據(jù)社會setter、getter、watcher),然后對比新舊dom,得出新舊dom不同,更新真實dom。但是,react給開發(fā)者暴露一個生命周期函數(shù):shouldcomponentupdate,這個函數(shù)可以根據(jù)開發(fā)者的需求決定數(shù)據(jù)發(fā)生變化決定是否重新渲染。
react是 函數(shù)式組件思想,當(dāng)你 setstate 就會遍歷,diff 當(dāng)前組件所有的子節(jié)點子組件, 這種方式開銷是很大的,要合理使用shouldcomponentupdate。
vue為每個數(shù)據(jù)設(shè)置setter、getter、watcher,當(dāng)數(shù)據(jù)足夠多時,運行效率反倒不如react。
所以在選擇框架時,要衡量一下,如果頁面數(shù)據(jù)量大,變化多,選react,而如果項目中型,并且想快速開發(fā),選vue。
“怎么用js對象生成dom結(jié)構(gòu)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!