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

資訊專欄INFORMATION COLUMN

【Vue原理】Event - 源碼版 之 綁定組件自定義事件

amuqiao / 2322人閱讀

摘要:寫文章不容易,點(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原理】Event - 源碼版 之 綁定組件自定義事件

組件自定義事件其實(shí)是我最感興趣的,我當(dāng)時(shí)花了好多時(shí)間去探索的哈哈哈,探索完了之后,發(fā)現(xiàn)很簡單的,可以先看下白話版了解下

【Vue原理】Event - 白話版

我當(dāng)時(shí)腦海中就幾個(gè)問題,我很想弄懂啊

1、父給子綁定的事件,存放在父組件還是子組件?

2、父給子綁定自定義事件,子組件為什么可以觸發(fā)?

3、子組件觸發(fā)事件后,是怎么調(diào)用綁定的 父組件的方法的?

看看當(dāng)時(shí)做的筆記時(shí)間,已經(jīng)過了好久了啊

筆記看著很混亂,所以下定決心寫文章,寫得詳詳細(xì)細(xì)的,然自己一眼就明白,而且怕以后自己忘記

首先肯定是為自己服務(wù)的,只是順便分享給大家,能幫到別人少走彎路而已哈哈哈

好的,不多說了,馬上進(jìn)入主題~~看完文章的歡迎到下面投票啊啊啊啊

怎么解析

同樣,一個(gè)給組件綁定自定義事件的模板

然后template 解析成下面的渲染函數(shù)

渲染函數(shù)執(zhí)行,生成這樣的組件外殼VNode

還可以打印組件實(shí)例看一下

你可以看到,綁定的自定義事件,存在了 組件外殼VNode的 componentOptions.listeners 中

等下!

渲染函數(shù)中,明明把事件解析放在 on 的啊,怎么到 listeners了

這里記錄一下哈

當(dāng) _c("test") 執(zhí)行的時(shí)候,因?yàn)槭墙M件,所以內(nèi)部會(huì)特別調(diào)用 createComponent 去生成組件的VNode

而這個(gè)VNode 是外殼VNode

下面的源碼中可以很清楚的看到

1、把 on 賦值給了 listeners

2、listeners 傳給了 VNode 構(gòu)造函數(shù),保存到了 vnode.componentOptions

function createComponent(
    Ctor, data, context, 
    children, tag
) {    

    var listeners = data.on;

    data.on = data.nativeOn;    

    var vnode = new VNode(

        tag, // 組件名字
        data, undefined, undefined, 
        undefined, context,    
        // 下面這個(gè)對(duì)象就存在 vnode.componentOptions
        {            
            listeners: listeners,
        }
    );    

    return vnode

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

) {  
    this.componentOptions = componentOptions;

};

想了解多一點(diǎn)Vnode可以看 VNode - 源碼版

想了解 component 流程的,可以看 Component - 白話版

所以第一個(gè)問題得到答案,父給子綁定的事件,存放在子組件中!

怎么綁定

好的,模板上的事件已經(jīng)被解析并保存好了

接下來,就輪到 事件的注冊(cè) showtime

這個(gè)事情,發(fā)生在創(chuàng)建組件實(shí)例的時(shí)候

如果你要問,具體是怎么到了創(chuàng)建實(shí)例這里的話,你可以看下面兩篇文章,不過看你有沒有這個(gè)耐心了(學(xué)習(xí)的事,能不要耐心嗎)

Component - 源碼版 之 創(chuàng)建組件VNode

Component - 源碼版 之 掛載組件DOM

要不就看白話版吧

Component - 白話版

1、初始化實(shí)例

組件實(shí)例初始化會(huì)調(diào)用 Vue.prototype._init 沒錯(cuò)了

然后 _init 會(huì)調(diào)用一個(gè) initEvents 的東東去進(jìn)行初始化事件對(duì)象,如下

Vue.prototype._init = function(options) {  

    // 增加組件選項(xiàng),詳情往下看
    initInternalComponent(vm,options);

    initEvents(vm);    

    ....處理選項(xiàng)數(shù)據(jù)

}

initEvents:沒錯(cuò)就是我!

2、初始化事件對(duì)象

initEvent 這個(gè)函數(shù)做了什么事情呢?

1、給實(shí)例上添加一個(gè) _event 對(duì)象,用于保存自定義事件

2、獲取到 父組件給 子組件綁定的自定義事件(不懂就接著往下看)

3、調(diào)用 updateComponentListeners 開始注冊(cè)

function initEvents(vm) {

    vm._events = Object.create(null);    

    var listeners = vm.$options._parentListeners;    

    if (listeners) {

        updateComponentListeners(vm, listeners);
    }
}

有個(gè)疑惑

_parentListeners 保存的是什么東西?父組件給子組件的事件?

百思不得其解,誒,看到_init 中有一句代碼調(diào)用initInternalComponent,也許就是這個(gè)函數(shù)搞的鬼,我們來看下

3、初始化組件信息
function initInternalComponent(vm, options) { 

    .....保存節(jié)點(diǎn)等信息
    
    // _parentVnode 是外殼節(jié)點(diǎn)
    var parentVnode = options._parentVnode; 
    
    // 保存父組件給子組件關(guān)聯(lián)的數(shù)據(jù)
    var vcp= parentVnode.componentOptions;

    vm.$options._parentListeners =vcp.listeners;   

    ....保存渲染函數(shù)

}

這個(gè)函數(shù)的作用是初始化一些組件的信息,包括轉(zhuǎn)移一些數(shù)據(jù)

哦~~原來就是通過這個(gè)函數(shù)偷偷摸摸轉(zhuǎn)移了 listeners 到了 vm.$option._parentListeners

前面說過【父給子綁定的事件】解析存放在 外殼節(jié)點(diǎn)vnode.componentOptions.listeners 中(不明白可以翻到上面的<怎么解析>部分),然后轉(zhuǎn)移的就是這個(gè) listeners

解決這個(gè)疑惑了,好的,我們接著來走 initEvent 剩下的流程把~~

來看下 updateComponentListeners

4、注冊(cè)事件
function updateComponentListeners(
    vm, listeners, oldListeners

) {

    var name, cur, old;    

    for (name in listeners) {

        cur = listeners[name];

        old = oldListeners[name];   

        // 沒有舊事件,就直接添加新事件

        if (typeof old === "undefined") {
            vm.$on(name, cur);
        }      

        // 新事件和舊事件不一樣,替換舊事件
        else if (cur !== old) {
            on[name] = cur;
        }
    }    

    // 移除舊事件
    for (name in oldListeners) {        

        if (typeof listeners[name] === "undefined") {

            vm.$off(name, oldOn[name]);
        }
    }
}

就是從他這里開始注冊(cè)事件的

似乎沒什么好說的,注意一點(diǎn)

綁定和解綁事件,是直接調(diào)用 Vue 的自定義事件方法 $on 和 $off ,大家是不是很熟悉???

沒錯(cuò),在這篇文章中說過

【Vue原理】Event - 源碼版 之 自定義事件

這就解釋我們開篇第二個(gè)問題了!?。?!

為什么我給子組件綁定自定義事件,可以在子組件像下面這樣觸發(fā)?

this.$emit("test")

因?yàn)?組件綁定的自定義事件 和 Vue 的自定義事件

兩種事件都是使用同一種方法注冊(cè)的,所以都存在同樣一個(gè)事件對(duì)象 【vm._events】 中,是一樣操作的流程

就是這樣的

可以看到組件實(shí)例上的 _events

并且知道了第三個(gè)問題,怎么調(diào)用到父組件的方法?

因?yàn)榻o子組件注冊(cè)事件的時(shí)候,直接存放父組件的回調(diào),所以觸發(fā)事件會(huì)調(diào)用到父組件的方法

然后你還可以問出一個(gè)問題!

為什么子組件觸發(fā)事件之后,調(diào)用父組件的方法,而父組件的方法上下文對(duì)象還是父組件

哈哈,因?yàn)?methods 方法已經(jīng)使用 bind 綁定啦,上下文對(duì)象固定了為父組件實(shí)例的,所以不管誰調(diào)用,怎么調(diào)用,都是父組件

詳情可以看這里,

Methods - 源碼版

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

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

相關(guān)文章

  • Vue原理】Compile - 源碼 generate 拼接綁定事件

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

    OnlyMyRailgun 評(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í)吧研究基于...

    kumfo 評(píng)論0 收藏0
  • Vue原理Event - 源碼 綁定組件DOM事件

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

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

    yunhao 評(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

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

0條評(píng)論

amuqiao

|高級(jí)講師

TA的文章

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