文章前提:已經clone下來vue原始碼
直接進入主題,computed計算屬性的初始化位置是在new Vue的時候初始化的。
檢視順序:
1、/src/core/instance/index.js 中的initMixin函式執行中
2、initMixin函式在/src/core/instance/init.js中,函式有呼叫initState函式(注意初始化是在created生命週期之前)
3、在initState函式中可以看到data、props、methods、computed、watch都在這裡初始化的
這裡我們就看到initComputed函式了,這個函式的引數為兩個,vm為vue例項,computed為我們定義的computed。
我們一步一步來解析
1、初始化一個儲存計算屬性的空物件
2、判斷當前是否是服務端渲染
3、遍歷computed的每一個key,獲取key對應的value,因為我們在寫計算屬性是有兩個方式的,一種是寫一個函式直接返回value(getter函式),另一種是我們去自定義get、set屬性,所以這裡會判斷value是否為函式來取getter函式
4、環境判斷先不說了
5、在非服務端渲染的時候,vue會為computed中的每一個key建立一個watcher,並儲存在第一行初始化的物件中
6、這個vue會判斷computed中的key是否已經在例項中定義過,如果未定義的話,則執行defineComputed函式
接下來我們來看一下defineComputed函式
這裡擷取了兩個函式,defineComputed和createComputedGetter兩個函式
先說說defineComputed函式,還是離不開get、set屬性
1、判斷當前是否為服務端渲染,如果為服務端渲染則將計算屬性的get、set定義為使用者定義get、set;如果非服務端渲染的話則在定義get屬性的時候並沒有直接賦值使用者函式,而是返回一個新的函式computedGetter
2、這裡會判斷userDef也就是使用者定義計算屬性key對應的value值是否為函式,如果為函式的話,則將get定義為使用者函式,set賦值為一個空函式noop;如果不為函式(物件)則分別取get、set欄位賦值
3、在非服務端渲染中計算屬性的get屬性為computedGetter函式,在每次計算屬性觸發get屬性時,都會從例項的_computedWatchers(在initComputed已初始化)計算屬性的watcher物件中獲取get函式(使用者定義函式)
4、最終會把當前key定義到vue例項上,也就是可以this.computedKey可以獲取到的原因
到此計算屬性就這樣初始化結束了。
emmmm.....第一次寫文章,可能語言什麼的都不太好,多多包容,如果有什麼建議歡迎提出哈,謝謝啦