成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【Vue原理】VNode - 源碼版

layman / 3215人閱讀

摘要:表示虛擬節(jié)點(diǎn),為什么叫虛擬節(jié)點(diǎn)呢,因?yàn)椴皇钦娴墓?jié)點(diǎn)。因?yàn)槭菍?duì)象,不管還是瀏覽器,都可以統(tǒng)一操作,從而獲得了服務(wù)端渲染原生渲染手寫渲染函數(shù)等能力減少操作。

寫文章不容易,點(diǎn)個(gè)贊唄兄弟
專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧
研究基于 Vue版本 【2.5.17】

如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也可以吧

【Vue原理】VNode - 源碼版

今天就來(lái)探索 VNode 的源碼,VNode 是 Vue2 渲染機(jī)制中很重要的一部分,是深入Vue 必須了解的部分

我們以4個(gè)問(wèn)題來(lái)開始我們的探索

1、vnode 是什么及其作用

2、vnode 什么時(shí)候生成

3、vnode 怎么生成

4、vnode 存放什么信息

5、vnode 存放在哪里

文章很長(zhǎng),看之前值做好準(zhǔn)備

VNode是什么及作用

首先,第一個(gè)問(wèn)題已經(jīng)很爛了,網(wǎng)上有很多相關(guān)的內(nèi)容,為了內(nèi)容的完整性,所以也放上來(lái)哈哈。

VNode 表示 虛擬節(jié)點(diǎn) Virtual DOM,為什么叫虛擬節(jié)點(diǎn)呢,因?yàn)椴皇钦娴?DOM 節(jié)點(diǎn)。

他只是用 javascript 對(duì)象來(lái)描述真實(shí) DOM,這么描述,把DOM標(biāo)簽,屬性,內(nèi)容都變成 對(duì)象的屬性

就像用 JavaScript 對(duì)象描述一個(gè)人一樣

{sex:"男", name:"神仙朱", salary:5000,children:null}

過(guò)程就是,把你的 template 模板 描述成 VNode,然后一系列操作之后通過(guò) VNode 形成真實(shí)DOM進(jìn)行掛載

是什么?

JavaScript 對(duì)象

什么用?

1、兼容性強(qiáng),不受執(zhí)行環(huán)境的影響。VNode 因?yàn)槭?JS 對(duì)象,不管 Node 還是 瀏覽器,都可以統(tǒng)一操作, 從而獲得了服務(wù)端渲染、原生渲染、手寫渲染函數(shù)等能力

2、減少操作 DOM。任何頁(yè)面的變化,都只使用 VNode 進(jìn)行操作對(duì)比,只需要在最后一步掛載更新DOM,不需要頻繁操作DOM,從而提高頁(yè)面性能

VNode怎么生成

在 Vue 源碼中,vnode 是通過(guò)一個(gè)構(gòu)造函數(shù)生成的,構(gòu)造函數(shù)看起來(lái)挺簡(jiǎn)單的

本來(lái)以為很多內(nèi)容,帶著沉重的心情去探索,然后看到之后就放松了下來(lái),看了一會(huì),心情再次沉重了起來(lái)

其中涉及的內(nèi)容還是挺多的....不然哪里來(lái)開篇的那么多問(wèn)題

行了,看下 VNode 的構(gòu)造函數(shù)

function VNode(
    tag, data, children, 
    text, elm, context, 
    componentOptions

) {    

    this.tag = tag; // 標(biāo)簽名

    this.data = data;    

    this.children = children; // 子元素

    this.text = text; // 文本內(nèi)容

    this.elm = elm; // Dom 節(jié)點(diǎn)



    this.context = context;    

    this.componentOptions = componentOptions;    

    this.componentInstance = undefined;    

    this.parent = undefined;    

    this.isStatic = false; // 是否靜態(tài)節(jié)點(diǎn)

    this.isComment = false; // 是否是注釋節(jié)點(diǎn)

    this.isCloned = false; // 是否克隆節(jié)點(diǎn)

};

看完上面,先不要糾結(jié)都是什么東西,先來(lái)走一遍

比如我們使用 vnode 去描述這樣一個(gè)template

111111

使用 VNode 構(gòu)造函數(shù)就可以生成下面的 VNode

{    

    tag: "div",    

    data: {        

        attrs:{href:"2222"}

        staticClass: "parent",        

        staticStyle: {            

            height: "0"

        }
    },    

    children: [{        

        tag: undefined,        

        text: "111111"

    }]
}

這個(gè) JS 對(duì)象,就已經(jīng)囊括了整個(gè)模板的所有信息,完全可以根據(jù)這個(gè)對(duì)象來(lái)構(gòu)造真實(shí)DOM了

至于其中都是什么意思,請(qǐng)看下個(gè)問(wèn)題

VNode存放什么信息

新建一個(gè) vnode 的時(shí)候,包含了非常多的屬性,每個(gè)屬性都是節(jié)點(diǎn)的描述的一部分

我們只撿一些屬性來(lái)探索一下,了解主體即可

普通屬性

1、data

1、存儲(chǔ)節(jié)點(diǎn)的屬性,class,style 等

2、存儲(chǔ)綁定的事件

3、....其他

2、elm

真實(shí)DOM 節(jié)點(diǎn)

生成VNode 的時(shí)候,并不存在真實(shí) DOM

elm 會(huì)在需要?jiǎng)?chuàng)建DOM 時(shí)完成賦值,具體函數(shù)在 createElm 中

賦值語(yǔ)句就是一句(簡(jiǎn)化了源碼)

3、context

渲染這個(gè)模板的上下文對(duì)象

意思就是,template 里面的動(dòng)態(tài)數(shù)據(jù)要從這個(gè) context 中獲取,而 context 就是 Vue 實(shí)例

如果是頁(yè)面,那么context 就是本頁(yè)面的實(shí)例,如果是組件,context則是組件的實(shí)例

4 isStatic

是否是靜態(tài)節(jié)點(diǎn)

當(dāng)一個(gè)節(jié)點(diǎn)被標(biāo)記為靜態(tài)節(jié)點(diǎn)的時(shí)候,說(shuō)明這個(gè)節(jié)點(diǎn)可以不用去更新它了,當(dāng)數(shù)據(jù)變化的時(shí)候,可以忽略去比對(duì)他,以提高比對(duì)效率

組件相關(guān)屬性

1、parent

這個(gè)parent 表示是組件的外殼節(jié)點(diǎn)

額,什么是外殼節(jié)點(diǎn),舉個(gè)栗子先吧

1、存在這樣一個(gè)組件 test

2、頁(yè)面中使用這個(gè)組件

誒,到這里就有意思了,組件其實(shí)應(yīng)有兩種 VNode

這兩種VNode 名義上都是對(duì)的,都有理,誰(shuí)是正牌不好說(shuō)

最后尤大判定第一個(gè) VNode 是 第二個(gè) VNode 的爸爸,也就是外殼節(jié)點(diǎn)

外殼節(jié)點(diǎn)通常是 父組件和 子組件的 關(guān)聯(lián),用于保存一些父組件傳給子組件的數(shù)據(jù) 等

2 componentInstance

這個(gè)顧名思義,就是組件生成的實(shí)例,保存在這里

上面 test 組件的外殼節(jié)點(diǎn)中的 componentInstance

3 componentOptions

這個(gè)就存儲(chǔ)一些 父子組件 PY 交易的證據(jù)

比如 props,事件,slot 什么的,打印看下

其中 children 保存的就是 slot,listeners 保存 事件,propsData 保存 props

VNode怎么生成

在初始化完選項(xiàng),解析完模板之后,就需要掛載 DOM了。此時(shí)就需要生成 VNode,才能根據(jù) VNode 生成 DOM 然后掛載

掛載 DOM 第一步,就是先執(zhí)行渲染函數(shù),得到整個(gè)模板的 VNode

比如有以下渲染函數(shù),執(zhí)行會(huì)返回 VNode,就是 _c 返回的VNode

function (){ 
    with(this){  
        return _c("div",{attrs:{"href":"xxxx"}},["1111"]).
    } 
}

渲染函數(shù)會(huì)綁定上下文對(duì)象,加上 with 的作用,_c 其實(shí)就是 vm._c

現(xiàn)在就來(lái)看 vm._c 是什么東西

vm._c = function(a, b, c, d) {    

    return createElement(vm, a, b, c, d, false);

};
function createElement(

    context, tag, data, 

    children, normalizationType

) {    

    var vnode;    

    if (tag是正常html標(biāo)簽) {

        vnode = new VNode(

            tag, data, children, undefined, 

            undefined, context

        );
    } 
    else if (tag 是組件) {
        vnode = createComponent(

            Ctor, data, context, 

            children, tag

        );

    }    

    return vnode

}

我們可以看到,正常標(biāo)簽 和 組件會(huì)走不同流程

1 、正常標(biāo)簽

比如有這樣一個(gè)正常標(biāo)簽?zāi)0?/p>

解析成渲染函數(shù)如下

function (){    

    with(this){  

        return _c("div",{

            attrs:{"href":"xxxx"}},

            ["1111"]

        )

    }
}

看上面_c 源碼,可以知道經(jīng)過(guò) _c 把參數(shù)傳導(dǎo),這樣去構(gòu)建 VNode

new VNode(tag, data, children, undefined, undefined, context);

這樣就保存了 tag,data,children 和 context

2、組件

比如頁(yè)面使用了test組件

解析成渲染函數(shù)如下

with(this){  
    return _c("div",[
        _c("test",
            {attrs:{"name":name}},
            ["1111"]
        )
    ],1)
}

看上面 _c 代碼知道 ,_c 會(huì)先調(diào)用 createComponent

createComponent(Ctor, data, context, children, tag);}

createComponent 中也會(huì)調(diào)用 VNode 構(gòu)造函數(shù),生成VNode 并返回

function createComponent(

    Ctor, data, context, 

    children, tag

) {    

    // extractPropsFromVNodeData 作用是把傳入data的 attr 中屬于 props的篩選出來(lái)
    var propsData = extractPropsFromVNodeData(data, Ctor, tag);    


    var vnode = new VNode(

        ("vue-component-" + (Ctor.cid) + tag),
        data, undefined, undefined, undefined,

        context, {            

            Ctor: Ctor, 

            // 父組件給子組件綁定的props
            propsData: propsData, 

            // 父組件給子組件綁定的事件
            listeners: listeners, 

            tag: tag,            

            children: children

        });    

    return vnode

}
VNode存放在哪里

那么創(chuàng)建出來(lái)的 VNode 是否有被存起來(lái),毫無(wú)疑問(wèn),肯定是要的啊

主要是三個(gè)位置存了 vnode,分別是

parent ,_vnode ,$vnode

parent 上面已經(jīng)說(shuō)過(guò),就先不提了,剩下兩個(gè)全部是掛在 Vue 實(shí)例一級(jí)屬性上的

打印一下組件的實(shí)例,可以很清楚看到這兩個(gè)屬性

下面來(lái)說(shuō)說(shuō)這兩個(gè)東西

1、_vnode

_vnode 存放表示當(dāng)前節(jié)點(diǎn)的 VNode

什么叫當(dāng)前,也就是可以通過(guò)這個(gè)VNode 直接映射成 當(dāng)前真實(shí)DOM

他的作用是什么呢?

用來(lái)比對(duì)更新,比如你的數(shù)據(jù)變化了,此時(shí)會(huì)生成一個(gè)新的 VNode,然后再拿到保存的_vnode 對(duì)比,就可以得到最小區(qū)域,從而只用更新這部分

所以, _vnode 存放的可以說(shuō)是當(dāng)前節(jié)點(diǎn),也可以說(shuō)是舊節(jié)點(diǎn)

另外,_vnode 中保存有一個(gè) parent,這個(gè)parent 就是外殼節(jié)點(diǎn),上面說(shuō) vnode 的時(shí)候已經(jīng)說(shuō)過(guò)了

在哪里賦值?

我們來(lái)完整地走一遍流程,涉及源碼很多,但是我已經(jīng)非常精簡(jiǎn)了,大概了解個(gè)流程

function Vue() {
    ...初始化組件選項(xiàng)等
    mountComponent()

}

function mountComponent() {

    ....解析模板,生成渲染函數(shù)
   
    // 用于生成VNode,生成DOM,掛載DOM
    updateComponent = function() {
        vm._update(vm._render());
    };    

    // 新建 watcher,保存updateComponent為更新函數(shù),新建的時(shí)候會(huì)立即執(zhí)行一遍
    new Watcher(vm, updateComponent)
}

function Watcher(vm, expOrFn) {    

    this.getter = expOrFn ;    

    this.getter()

}

// 執(zhí)行前面解析得到的渲染函數(shù),返回生成的 VNode
Vue.prototype._render = () {}

// 根據(jù)vnode,生成DOM 掛載
Vue.prototype._update = function(vnode) {    

    var prevVnode = vm._vnode;

    vm._vnode = vnode;    

    if (不存在舊節(jié)點(diǎn)) { ...使用vnode創(chuàng)建DOM并直接掛載 }    

    else { ...存在舊節(jié)點(diǎn),開始比對(duì)舊節(jié)點(diǎn)和新節(jié)點(diǎn),然后創(chuàng)建DOM并掛載 }

}
2、$vnode

$vnode 只有組件實(shí)例才有,因?yàn)?$vnode 存放的是外殼節(jié)點(diǎn),頁(yè)面實(shí)例中是不存在 $vnode 的

本來(lái)也想走下流程的,無(wú)奈兜兜轉(zhuǎn)轉(zhuǎn)太多,涉及源碼更多

在哪里進(jìn)行賦值?

我就放最后一步 updateChildComponent

updateChildComponent 會(huì)在上個(gè) _vnode 提到的 vm._update 執(zhí)行流程中調(diào)用

function updateChildComponent(
    vm, parentVnode

) {

    vm.$options._parentVnode = parentVnode;
    vm.$vnode = parentVnode; 
    if (vm._vnode) {
        vm._vnode.parent = parentVnode;
    }
}
最后

鑒于本人能力有限,難免會(huì)有疏漏錯(cuò)誤的地方,請(qǐng)大家多多包涵,如果有任何描述不當(dāng)?shù)牡胤?,歡迎后臺(tái)聯(lián)系本人,有重謝

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105388.html

相關(guān)文章

  • Vue原理】Event - 源碼 之 綁定組件DOM事件

    摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號(hào)也可以吧原理源碼版之綁定組件事件上一篇已經(jīng) 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...

    Mr_zhang 評(píng)論0 收藏0
  • Vue原理】Component - 源碼 之 創(chuàng)建組件VNode

    摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號(hào)也可以吧原理源碼版之創(chuàng)建組件今天就要開啟我 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...

    hover_lew 評(píng)論0 收藏0
  • Vue原理】Event - 源碼 之 綁定標(biāo)簽DOM事件

    摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號(hào)也可以吧原理源碼版之綁定標(biāo)簽事件這里的綁定 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...

    phoenixsky 評(píng)論0 收藏0
  • Vue原理】Event - 源碼 之 綁定組件自定義事件

    摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號(hào)也可以吧原理源碼版之綁定組件自定義事件組件 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...

    amuqiao 評(píng)論0 收藏0
  • Vue原理】Component - 源碼 之 掛載組件DOM

    摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號(hào)也可以吧原理源碼版之掛載組件由這篇文章從模 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...

    lbool 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<