摘要:寫文章不容易,點(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í)吧
研究基于 Vue版本 【2.5.17】
如果你覺得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也可以吧
【Vue原理】Component - 源碼版 之 創(chuàng)建組件VNode
今天就要開啟我們 Component 探索之旅,旅途有點(diǎn)長(zhǎng),各位請(qǐng)坐好,不要睡著了
內(nèi)容的主題是,Component 的創(chuàng)建過程,從調(diào)用 component,到 component 掛載,到底經(jīng)歷了什么?歡迎來(lái)到 component 的內(nèi)心世界
建議可以先看看白話版
Component - 白話版
Component 創(chuàng)建,我主要分了兩個(gè)流程
1、創(chuàng)建 組件 VNode 2、掛載 組件 DOM
每個(gè)流程涉及源碼都很多,所以每個(gè)流程寫一篇文章。沒錯(cuò)了,今天講的就是 創(chuàng)建組件 VNode
場(chǎng)景設(shè)置首先,我們假定現(xiàn)在有這么一個(gè)模板,使用了 test 組件
然后頁(yè)面噼里啪啦執(zhí)行到了 準(zhǔn)備掛載DOM 的步驟(之前的部分跟本主題無(wú)關(guān),跳過)
然后頁(yè)面準(zhǔn)備執(zhí)行渲染函數(shù) render,嗯,就是執(zhí)行上面模板生成的渲染函數(shù),如下
沒有錯(cuò),我們的 Vue 已經(jīng)走到了這一步,那么我們的突破口是什么?
沒錯(cuò),就是 _c
function _createElement( context, tag, data, children ) { var vnode; var options = context.$options // 從父組件選項(xiàng)上拿到 對(duì)應(yīng)的組件的選項(xiàng) var Ctor = options.components[tag] if (正常的HTML標(biāo)簽) { ....直接新建VNode } else if ( Ctor ) { vnode = createComponent( Ctor, data, context, children, tag ); } return vnode }
今天講的是 component,跳過其他,直接走到 第二個(gè) if,嗯,他調(diào)用了一個(gè) createComponent
好的,我去前面探探路
function createComponent( Ctor, data, context, children, tag ) { var baseCtor = context.$options._base; // 創(chuàng)建組件構(gòu)造函數(shù) Ctor = baseCtor.extend(Ctor); var vnode = new VNode( "vue-component-" + (Ctor.cid) + name, data, undefined, undefined, undefined, context, { Ctor: Ctor } ); return vnode }
這個(gè) createComponent 什么鬼的,作用大概是
1、創(chuàng)建組件構(gòu)造函數(shù)
2、處理父組件給子組件的數(shù)據(jù)
3、創(chuàng)建組件 外殼 VNode
由于處理數(shù)據(jù)什么的,跟本內(nèi)容無(wú)關(guān),所以其他源碼一律去掉,那么就只剩下兩個(gè)流程
下面就開始這兩個(gè)流程
創(chuàng)建組件構(gòu)造函數(shù)上面的源碼中有兩句話(如下),作用就是為組件創(chuàng)建一個(gè)構(gòu)造函數(shù)!
var baseCtor = context.$options._base; Ctor = baseCtor.extend(Ctor);
看得懂嗎?看懂了?好吧,那我就不講了
算了,算了,還是講吧,畢竟當(dāng)時(shí)自己也是懵逼的
首先,context 是什么?context 是執(zhí)行整個(gè)渲染函數(shù)的上下文對(duì)象,很明顯,這里就是頁(yè)面的 實(shí)例vm 了
那么,$options 是什么?$options 就是 實(shí)例自定義選項(xiàng) 和 全局選項(xiàng)合并之后的 產(chǎn)物
Vue.prototype._init = function(options) { ..... vm.$options = mergeOptions( // 把兩個(gè)對(duì)象合并 vm.constructor.options, options, vm ); ..... }vm.constructor 是什么?
沒錯(cuò),就是 Vue,你使用 new Vue 創(chuàng)建的頁(yè)面,構(gòu)造函數(shù)肯定是 Vue 啦
vm.constructor.options 是什么?看下面
Vue.options = Object.create(null); Vue.options.components = Object.create(null); Vue.options.directives = Object.create(null); Vue.options.filters = Object.create(null); Vue.options._base = Vue;
Vue 在引入的時(shí)候,就完成了很多初始化的內(nèi)容,這里就是其中給 Vue 增加options 的部分
你看到的 component 啊,filter 什么的啊,沒錯(cuò),保存的就是你全局注冊(cè)的 component,filter
然后每個(gè)頁(yè)面都能使用到 全局組件,全局filter 的原因
就是因?yàn)樵?頁(yè)面實(shí)例初始化的時(shí)候,把 頁(yè)面選項(xiàng) 和 全局選項(xiàng)私下合并 了
然后,你應(yīng)該能看到這一句,保存了 Vue 構(gòu)造函數(shù)在 options._base 中
Vue.options._base = Vue;
那么,你應(yīng)該能理解前面出現(xiàn)的源碼了
var baseCtor = context.$options._base;
沒錯(cuò)!baseCtor 拿到的就是 Vue!?。?!
然后還有一句
Ctor = baseCtor.extend(Ctor);
既然 baseCtor 是 Vue,那 baseCtor.extend 是 Vue.extend?沒有錯(cuò)!
正是他!完成了創(chuàng)建組件構(gòu)造函數(shù)的偉大之舉?。∽屛覀円黄饋?lái)欣賞下
Vue.extend = function(extendOptions) { // this 指向Vue var Super = this; var Sub = function VueComponent(options) { this._init(options); }; // 原型鏈繼承 Sub.prototype = Object.create(Super.prototype); Sub.prototype.constructor = Sub; // Super 永遠(yuǎn)是 Vue,所以這里就是 合并全局選項(xiàng) // 現(xiàn)在 Super 就是 vue,把 Vue 和 Sub 合并 // 是把一些全局的組件 指令合并到 Sub 中 Sub.options = mergeOptions( // optios 還包括 mixins 注入的全局 Super.options, extendOptions ); return Sub };
這個(gè)函數(shù),會(huì)返回一個(gè)函數(shù) VueComponent,他就是組件的構(gòu)造函數(shù)!用來(lái)下篇文章創(chuàng)建組件實(shí)例的!!
上面的源碼,做的事,簡(jiǎn)單說(shuō),就是繼承父類Vue,然后合并 options 等
最后,提一下,所有實(shí)例的父類構(gòu)造函數(shù) Super 都是 Vue
并不是說(shuō),組件 a 有一個(gè)子組件b,然后組件b 的父類構(gòu)造函數(shù)就是 a.contructor,這是不對(duì)的,永遠(yuǎn)是Vue,誰(shuí)都是 Vue
創(chuàng)建組件外殼VNode現(xiàn)在就是前面代碼 createComponent 中的最后一步了
注意注意,這里創(chuàng)建的是【組件外殼節(jié)點(diǎn)】,內(nèi)部節(jié)點(diǎn)還沒有上場(chǎng),在下篇文章才出現(xiàn)
至于,什么是外殼節(jié)點(diǎn),去看下我的 VNode - 源碼版
跳到相關(guān)內(nèi)容看就好了
var vnode = new VNode( "vue-component-" + Ctor.cid + name, data, undefined, undefined, undefined, context, { Ctor: Ctor } );那么這個(gè)外殼節(jié)點(diǎn)的作用是什么?
1、保存剛創(chuàng)建好的組件構(gòu)造函數(shù),下篇文章中會(huì)調(diào)用到
2、保存父組件給子組件 關(guān)聯(lián)的數(shù)據(jù),比如 event,props 之類的(由于跟本主題無(wú)關(guān),為了整潔,統(tǒng)統(tǒng)去掉了)
總結(jié)Component 創(chuàng)建 外殼節(jié)點(diǎn)的流程,總結(jié)如下
1、頁(yè)面渲染函數(shù)執(zhí)行
2、_c("test") 執(zhí)行
3、createElement 碰到 tag 是一個(gè)組件
4、從父組件中,拿到 test 組件的options,傳入 createComponent (作用是創(chuàng)建構(gòu)造函數(shù)和 VNode)
5、createComponent 調(diào)用 Vue.extend 創(chuàng)建組件構(gòu)造函數(shù)
6、新建 VNode,并把構(gòu)造函數(shù)和父組件給子組件的數(shù)據(jù)保存進(jìn)去
7、返回 VNode
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105443.html
摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請(qǐng)點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號(hào)也可以吧原理源碼版之掛載組件由這篇文章從模 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...
摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請(qǐng)點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號(hào)也可以吧原理源碼版之綁定組件自定義事件組件 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...
摘要:寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請(qǐng)點(diǎn)擊下面鏈接或者拉到下面關(guān)注公眾號(hào)也可以吧原理白話版從模板上使用到掛載到頁(yè)面 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于...
摘要:寫文章不容易,點(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í)吧研究基于...
摘要:表示虛擬節(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)擊 下面鏈接 或者 拉到 下...
閱讀 3088·2021-10-27 14:16
閱讀 2893·2021-09-24 10:33
閱讀 2299·2021-09-23 11:21
閱讀 3241·2021-09-22 15:14
閱讀 832·2019-08-30 15:55
閱讀 1692·2019-08-30 15:53
閱讀 1780·2019-08-29 11:14
閱讀 2199·2019-08-28 18:11