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