真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

javascript基礎(chǔ)修煉(10)——VirtualDOM和基本DFS

javascript基礎(chǔ)修煉(10)——VirtualDOM和基本DFS

創(chuàng)新互聯(lián)建站于2013年開始,先為南潯等服務(wù)建站,南潯等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為南潯企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

1. Virtual-DOM是什么

Virtual-DOM,即虛擬DOM樹。瀏覽器在解析文件時(shí),會(huì)將html文檔轉(zhuǎn)換為document對(duì)象,在瀏覽器環(huán)境中運(yùn)行的腳本文件都可以獲取到它,通過操作document對(duì)象暴露的接口可以直接操作頁面上的DOM節(jié)點(diǎn)。但是DOM讀寫是非常耗性能的,很容易觸發(fā)不必要的重繪和重排,為了更好地處理DOM操作,Virtual-DOM技術(shù)就誕生了。Virtual-DOM就是在javascript中模擬真實(shí)DOM的結(jié)構(gòu),通過數(shù)據(jù)追蹤和狀態(tài)對(duì)比來減少對(duì)于真實(shí)DOM的操作,以此來提高程序的效率的一種技術(shù)。

Virtual-DOM技術(shù)是前端高性能的基石,它是真實(shí)document對(duì)象的抽象,通過對(duì)比新舊Virtual-DOM的區(qū)別,找出發(fā)生變化的DOM節(jié)點(diǎn),再利用算法得到相對(duì)更合理的DOM節(jié)點(diǎn)修改方案,最終再將方案應(yīng)用在document對(duì)象上來改變頁面的展示內(nèi)容。

主流前端SPA框架都離不開【Virtual-DOM模型 + DOM-Diff算法 + 生命周期鉤子】這樣的核心模型。

2. Virtual-DOM的基本結(jié)構(gòu)

在上一篇博文《javascript基礎(chǔ)修煉(9)——MVVM中雙向數(shù)據(jù)綁定的基本原理》中,我們通過document.getElementById()從真實(shí)DOM中獲得了帶有自定義屬性的待解析結(jié)構(gòu),這里是有一些問題的,實(shí)際的過程是先解析模板字符串得到虛擬DOM樹,最后生成真實(shí)的DOM樹。

實(shí)際上我們?cè)谑褂肧PA框架時(shí)所編寫的html模板,并沒有被直接當(dāng)做DOM片段加載到頁面上使用,而是將文件當(dāng)做字符串讀入到程序中,然后通過解析來生成Virtual-DOM樹,接著通過SPA框架的渲染函數(shù)來生成必要的片段后才生成真實(shí)的DOM節(jié)點(diǎn)。例如我們要生成下文示例的HTML片段(為了方便演示,示例中只涉及了類名和文本節(jié)點(diǎn)):


   
   
header-zone
core-content
暫未開發(fā)

我們需要構(gòu)建出一個(gè)簡(jiǎn)易模型來表達(dá)上面的結(jié)構(gòu):

virtualDom = {
    name:"body",
    props:{
        className:"main"
    },
    children:[{
        name:"div",
        props:{...},
        children:[...]
      },{
        name:"div",
        props:{...},
        children:[...]
      },{
        name:"div",
        props:{...},
        children:[...]
      }]
}

建立一個(gè)生成虛擬節(jié)點(diǎn)的輔助函數(shù):

//構(gòu)建DOM節(jié)點(diǎn)的輔助函數(shù)
function h(name, props, children) {
    return {
        name:name,
        props:props,
        children:children
    }
}
//手動(dòng)生成virtual-DOM
var tree = h('body',{className:'main'},[
       h('div',{className:'sideBar'},[
          h('ul',{className:'sideBarContainer'},[
               h('li',{className:'sideBarItem'},['sidebar-1']),
               h('li',{className:'sideBarItem'},['sidebar-2']),
               h('li',{className:'sideBarItem'},['sidebar-3']),
            ])
        ]),
       h('div',{className:'mainContent'},[
           h('div',{className:'header'},['header-zone']),
           h('div',{className:'coreContent'},['core-content']),
           h('div',{className:'footer'},['footer-zone']),
        ]),
       h('div',{className:'rightSide'},['暫未開發(fā)'])
    ]);

通過上面的方法得到的tree對(duì)象就涵蓋了模板片段中的結(jié)構(gòu)和關(guān)鍵信息。實(shí)際開發(fā)中并不需要像上面一樣手動(dòng)來填寫DOM結(jié)構(gòu),可以將模板字符串掛載到離線DOM節(jié)點(diǎn)上,然后在遞歸解析的同時(shí)來構(gòu)建Virtual-DOM就可以了。

3. 使用DFS從Virtual-DOM生成DOM

至此我們完成了模板的編譯,也得到了Virtual-DOM對(duì)象,但它似乎并沒有什么用處,畢竟我們已經(jīng)完成了對(duì)模板的解析,渲染出頁面沒什么問題,其實(shí)Virtual-DOM對(duì)于首屏來說并沒有什么特別重要的意義,它的價(jià)值在模型和視圖發(fā)生變化時(shí)才會(huì)體現(xiàn)。上一篇博文的末尾我們已經(jīng)提到了更新視圖時(shí)的效率問題,當(dāng)數(shù)據(jù)模型發(fā)生變化后,我們需要一個(gè)方法來收集所有需要修改的DOM,并為之提供高效的修改方式(你總不能一有變化就把整個(gè)網(wǎng)頁重新渲染,或者讓數(shù)據(jù)模型各自去修改各自綁定的DOM吧)。那么為了能夠收集所有DOM節(jié)點(diǎn)的變化,我們就需要遍歷所有節(jié)點(diǎn)。

對(duì)數(shù)據(jù)結(jié)構(gòu)和算法有一定了解的讀者很容易想到,遍歷解析一個(gè)Virtual-DOM實(shí)際上就是對(duì)其進(jìn)行先序深度優(yōu)先遍歷(Pre-Order Depth-First-Search),本節(jié)中,我們先預(yù)熱一下,使用這種方式來復(fù)現(xiàn)一下DOM結(jié)構(gòu)。

function dfswalking(tree) {
    var _childrenLength;
    //執(zhí)行動(dòng)作
    if (typeof tree.children[0] === 'string') {
        console.log(`<${tree.name} class="${tree.props.className}">${tree.children[0]}`);
    } else {
        console.log(`<${tree.name} class="${tree.props.className}">  -->`);
        for(var i = 0, _childrenLength = tree.children.length; i < _childrenLength; i++){
            dfswalking(tree.children[i]);
        }
    }
}

本例中僅打印出字符串的方式來展示,可以在控制臺(tái)看到輸出結(jié)果:

javascript基礎(chǔ)修煉(10)——VirtualDOM和基本DFS

下一篇博文中將分析如何通過domDiff(oldTree, newTree)的方法通過同樣的遍歷方法來收集變化并批量更新視圖。

4. 聲明

本篇只是部分原理的學(xué)習(xí)筆記,并不代表框架真實(shí)源碼的實(shí)現(xiàn)邏輯。


文章標(biāo)題:javascript基礎(chǔ)修煉(10)——VirtualDOM和基本DFS
本文鏈接:http://weahome.cn/article/gsdgjp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部