成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

【Vue原理】Component - 源碼版 之 掛載組件DOM

lbool / 3001人閱讀

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

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

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

【Vue原理】Component - 源碼版 之 掛載組件DOM

由這篇文章 從模板到DOM的簡要流程

我們知道,在生成 VNode 之后,下一步就是根據(jù) VNode 生成DOM然后掛載了

在本文開始之前你可以先看 Component - 白話版 先整體了解下component

現(xiàn)在開始我們的正文

上一篇文章 Component - 創(chuàng)建組件VNode ,我們已經(jīng)說到了 【頁面模板解析成 VNode 樹】的步驟

那今天就就到了 【頁面VNode生成DOM掛載】 了

等等,今天說的不是 Component 掛載DOM 嗎?跟頁面Vnode 有什么關(guān)系??是啊,component 的掛載肯定是跟著父頁面的啊,你自己掛?自掛東南枝嗎?

好了,廢話不說,馬上開始

前言預(yù)告

這篇 從模板到DOM的簡要流程 已經(jīng)說過下面的步驟

1vm._render 執(zhí)行得到 頁面VNode

2vm._update 拿到 頁面VNode ,會(huì)開始 patch,不斷比對(duì) 【舊VNode 和 剛拿到的新VNode】

對(duì)比完之后,會(huì)調(diào)用一個(gè) createElm 的方法去創(chuàng)建DOM,然后插入頁面

那現(xiàn)在,我們就從 createElm 這個(gè)方法突破,前面的流程跟本內(nèi)容無關(guān),一律略過

function createElm(vnode, parentElm, refElm) {    

    // 組件需要特殊處理

    if (createComponent(vnode, parentElm, refElm)) return

    ...正常的標(biāo)簽,需要不斷遞歸子節(jié)點(diǎn)調(diào)用 createElm ,

             然后生成DOM,并插入到父節(jié)點(diǎn)

}

createElm 的作用就是根據(jù) 標(biāo)簽名創(chuàng)建 DOM 節(jié)點(diǎn),然后掛載到父節(jié)點(diǎn)中,其中參數(shù)如下

parentElm == 父DOM 節(jié)點(diǎn)
refElm == 兄弟DOM節(jié)點(diǎn),你插入父節(jié)點(diǎn),可能也要知道插在誰附近不是嗎,不能亂插的

然后很明顯,createElm 每次掉要給你都會(huì)調(diào)用 【createComponent】 去檢測(cè)這個(gè)標(biāo)簽是否是組件

如果是組件,就會(huì)去創(chuàng)建這個(gè)組件的實(shí)例,并且 返回 true,從而不用去執(zhí)行 createElm 下面的部分

調(diào)用組件生命鉤子

看下 createComponent

function createComponent(vnode, parentElm, refElm) {    

    var data = vnode.data;    

    var hook = i.hook;    

    var init = i.init;    

    // 調(diào)用子組件的 init 方法, init 方法就是 Vue.prototype._init

    if (init) {        

        // 創(chuàng)建子組件的 vm 實(shí)例

        init(vnode, parentElm, refElm);        

        // 如果存在組件實(shí)例,就是上一步創(chuàng)建成功了

        if (vnode.componentInstance) {            

            return true

        }
    }
}

有沒有好奇 vnode.data.hook.init 是什么嗎?

他是每個(gè)組件,都會(huì)被 【注冊(cè)進(jìn)外殼節(jié)點(diǎn)的鉤子函數(shù)】,沒錯(cuò),就是下面的鉤子,源碼

什么是組件生命鉤子

沒錯(cuò),這就是那個(gè)鉤子的源碼

var componentVNodeHooks = {

    init(vnode, parentElm, refElm) {        

        var vm= 

          vnode.componentInstance = 
          createComponentInstanceForVnode(

              vnode,activeInstance, 

              parentElm, refElm

          );        

        // 因?yàn)?在 Vue.prototype._init 中 ,只有 $options存在 el,才會(huì)掛載 dom

        // 這里手動(dòng)掛載組件
        vm.$mount(vnode.elm);
    }
    ...

}

那么,鉤子是什么時(shí)候注冊(cè)的呢?

嗯,在上一篇文章,【創(chuàng)建組件外殼VNode的過程中】,然后保存到了外殼節(jié)點(diǎn)的 data 上

function createComponent(

    Ctor, data, context, 

    children, tag

) {


    ...創(chuàng)建組件構(gòu)造函數(shù)
    var hooks = data.hook || (data.hook = {});
    data.hook.init = componentVNodeHooks.init

    ...創(chuàng)建組件VNode,并保存組件構(gòu)造函數(shù) 和鉤子 等到 vnode 中

}

打印一下實(shí)際VNode,沒錯(cuò),有很多鉤子,但是現(xiàn)在只說 init

來吧,仔細(xì)看那個(gè)init 鉤子源碼,你可以看到調(diào)用了一個(gè)方法

createComponentInstanceForVnode

開始深入探索它.........

創(chuàng)建組件實(shí)例

createComponentInstanceForVnode 函數(shù)作用就是給 component 【增加定制options】 + 【調(diào)用組件構(gòu)造函數(shù)】

function createComponentInstanceForVnode(
    vnode, parent, 
    parentElm, refElm

) {    

    // 增加 component 特有options
    var options = {        

        _isComponent: true,        

        parent: parent, // 父實(shí)例

        _parentVnode: vnode, // 外殼節(jié)點(diǎn)
        _parentElm: parentElm , // 父DOM
        _refElm: refElm  // 兄弟DOM

    };    

    // vnode.components.Ctor 就是 構(gòu)造函數(shù) ,里面會(huì)調(diào)用 Vue.prototype._init

    return new vnode.componentOptions.Ctor(options)
}

vnode.componentOptions.Ctor 就是 構(gòu)造函數(shù),就是下面這個(gè),上篇文章 Component - 創(chuàng)建組件VNode 時(shí)保存在外殼節(jié)點(diǎn)的

function VueComponent(options) {    

    this._init(options); 

}

new 了之后,自然而然,走到了 _init 方法,在 init 方法中,有一個(gè)特殊照顧 component 的方法,專門給 component 實(shí)例設(shè)置options

"這一步跟 掛載組件DOM 沒什么關(guān)聯(lián),想去掉的,但是想想還是先保留下來,完整整個(gè)流程"

Vue.prototype._init = function(options) {    

    if (如果是組件) {

        initInternalComponent(vm, options);
    }
}

組件初始化 initInteralComponent

function initInternalComponent(vm, options) {    

    // 這個(gè)options 就是在創(chuàng)建構(gòu)造函數(shù)時(shí),合并的 options,全局選項(xiàng)和組件設(shè)置選項(xiàng)

    var opts = vm.$options = Object.create(vm.constructor.options);        
    
    // 保存父節(jié)點(diǎn),外殼節(jié)點(diǎn),兄弟節(jié)點(diǎn)等

    var parentVnode = options._parentVnode; // _parentVnode 是外殼節(jié)點(diǎn)
    opts.parent = options.parent; // options.parent 是 父實(shí)例
    opts._parentVnode = parentVnode;
    opts._parentElm = options._parentElm;

    opts._refElm = options._refElm;    

    // 保存父組件給子組件關(guān)聯(lián)的數(shù)據(jù)
    var vnodeComponentOptions = parentVnode.componentOptions;
    opts.propsData = vnodeComponentOptions.propsData;
    opts._parentListeners = vnodeComponentOptions.listeners;
    opts._renderChildren = vnodeComponentOptions.children;

    opts._componentTag = vnodeComponentOptions.tag;    

    // 保存渲染函數(shù)
    if (options.render) {
        opts.render = options.render;
        opts.staticRenderFns = options.staticRenderFns;
    }
}

這個(gè)時(shí)候, init 的過程就完成了

下一步就是到了 mount 過程

組件解析模板并掛載

可以再回看下 「componentVNodeHooks.init 」 那個(gè)鉤子源碼

在創(chuàng)建組件實(shí)例成功之后,會(huì)手動(dòng)調(diào)用實(shí)例 vm.$mount 進(jìn)行掛載,就是這句代碼完成的功能

然而,掛載的步驟,就是正常標(biāo)簽掛載的步驟了

詳情可以查看 從模板到DOM的簡要流程
的 mount 過程,是一毛一樣的,就不多說了

總結(jié)

1、父頁面已經(jīng)拿到了 VNode,其中會(huì)調(diào)用 createElm 根據(jù) VNode 生成DOM,進(jìn)行掛載

2、不斷的遞歸遍歷子節(jié)點(diǎn),使用 createComponent 判斷標(biāo)簽是否是組件

3、遇到組件,拿到組件外殼VNode 的data(data 保存有父組件給子組件的,事件,props,構(gòu)造函數(shù),鉤子)

4、從 data 中拿到 hook,hook 中拿到 init 鉤子,并執(zhí)行 init 鉤子

5、init 鉤子中,調(diào)用 createComponentInstanceForVnode 調(diào)用組件構(gòu)造函數(shù),并返回組件

6、init 鉤子中,使用上一步返回的實(shí)例,手動(dòng)調(diào)用 vm.$mount 進(jìn)行組件內(nèi)部模板解析渲染,并掛載

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/105470.html

相關(guān)文章

  • Vue原理Component - 源碼 創(chuàng)建組件VNode

    摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請(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原理Component - 白話

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

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

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

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

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

    phoenixsky 評(píng)論0 收藏0
  • Vue原理】VNode - 源碼

    摘要:表示虛擬節(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】 如果你覺得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下...

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

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

0條評(píng)論

閱讀需要支付1元查看
<