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

資訊專欄INFORMATION COLUMN

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

lbool / 2934人閱讀

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

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

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

【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 ,會開始 patch,不斷比對 【舊VNode 和 剛拿到的新VNode】

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

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

function createElm(vnode, parentElm, refElm) {    

    // 組件需要特殊處理

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

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

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

}

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

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

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

如果是組件,就會去創(chuàng)建這個組件的實例,并且 返回 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 實例

        init(vnode, parentElm, refElm);        

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

        if (vnode.componentInstance) {            

            return true

        }
    }
}

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

他是每個組件,都會被 【注冊進外殼節(jié)點的鉤子函數(shù)】,沒錯,就是下面的鉤子,源碼

什么是組件生命鉤子

沒錯,這就是那個鉤子的源碼

var componentVNodeHooks = {

    init(vnode, parentElm, refElm) {        

        var vm= 

          vnode.componentInstance = 
          createComponentInstanceForVnode(

              vnode,activeInstance, 

              parentElm, refElm

          );        

        // 因為 在 Vue.prototype._init 中 ,只有 $options存在 el,才會掛載 dom

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

}

那么,鉤子是什么時候注冊的呢?

嗯,在上一篇文章,【創(chuàng)建組件外殼VNode的過程中】,然后保存到了外殼節(jié)點的 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 中

}

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

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

createComponentInstanceForVnode

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

創(chuàng)建組件實例

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

function createComponentInstanceForVnode(
    vnode, parent, 
    parentElm, refElm

) {    

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

        _isComponent: true,        

        parent: parent, // 父實例

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

    };    

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

    return new vnode.componentOptions.Ctor(options)
}

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

function VueComponent(options) {    

    this._init(options); 

}

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

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

Vue.prototype._init = function(options) {    

    if (如果是組件) {

        initInternalComponent(vm, options);
    }
}

組件初始化 initInteralComponent

function initInternalComponent(vm, options) {    

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

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

    var parentVnode = options._parentVnode; // _parentVnode 是外殼節(jié)點
    opts.parent = options.parent; // options.parent 是 父實例
    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;
    }
}

這個時候, init 的過程就完成了

下一步就是到了 mount 過程

組件解析模板并掛載

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

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

然而,掛載的步驟,就是正常標簽掛載的步驟了

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

總結(jié)

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

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

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 鉤子中,使用上一步返回的實例,手動調(diào)用 vm.$mount 進行組件內(nèi)部模板解析渲染,并掛載

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

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

相關(guān)文章

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

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

    hover_lew 評論0 收藏0
  • Vue原理Component - 白話

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

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

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

    amuqiao 評論0 收藏0
  • Vue原理】Event - 源碼 綁定標簽DOM事件

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

    phoenixsky 評論0 收藏0
  • Vue原理】VNode - 源碼

    摘要:表示虛擬節(jié)點,為什么叫虛擬節(jié)點呢,因為不是真的節(jié)點。因為是對象,不管還是瀏覽器,都可以統(tǒng)一操作,從而獲得了服務(wù)端渲染原生渲染手寫渲染函數(shù)等能力減少操作。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下...

    layman 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<