從源碼中學Vue(三)深入理解計算屬性computed原理
歡迎來到我的《從源碼中學Vue》專題系列文章,更多精彩內容持續(xù)更新中,歡迎關注 :)

上一章節(jié)我們通過源碼分析了Vue中的methods對象下的方法是如何掛載到vm下,以及各方法內部的this為何是指向了vm對象。
其實在Vue中,還有一個特別有用的API,那就是computed計算屬性,那么我們接下來就通過源碼看看它內部做了什么吧!
本章目標
computed運行效果computed源碼中做了什么?欲分析源碼,我們首先要搞清楚在Vue中,computed是如何工作的。
請看示例:

大概說下computed計算屬性的用法,它本身是一個對象,對應的key值都將會被Object.defineProperty給兼聽到,也可以將對應的key直接像data中的數(shù)據(jù)一樣綁定到我們的模板字符串中去渲染。
接下來我們去看下里面的源碼吧。
首先還是找到對應的文件:node_modules\vue\src\core\iinstance\state.js
和之前說到的methods源碼一樣,它有一個initComputed方法,核心源碼就在這個方法中,走,進去看看。

在第175行中,源碼開始使用for in去遍歷對象,接下來我們看下這段源碼

首先,我們通過const userDef = computed[key]獲取到computed對象的中的value值,這個值的類型可以是function,也可以是對象,但是如果是對象的話,那么這個對象下一定要實現(xiàn)一個ge對象,否則會報Getter is missing for computed property
也就是說,我們還可以這樣寫

我們將total寫成一個對象,然后實現(xiàn)一個get方法
繼續(xù)往下看
const isSSR = isServerRendering()這段表示是否是SSR(服務器渲染),一般來說,我們的項目都是非服務器渲染的。所以這個isSSR返回一個false.
緊接著,如果是非SSR下,我們則給每一個computed屬性生成一個Watch實例,用于檢測computed的變化。

這里我們著重來看下這個參數(shù):computedWatcherOptions,源碼在前面是這樣定義的。

lazy:true,這一點在后面會非常有用
wather等我們后面涉及到兼聽的時候再去看源碼。
再拄后是這樣的:

判斷我們在computed中的key值是否在我們的data或者props中定義過,如果定義了,則拋出異常,沒有定義那就是開始調用defineComputed(vm, key, userDef)函數(shù)。
到這里,核心函數(shù)來啦,我們去看下defineComputed(vm, key, userDef)函數(shù)的實現(xiàn)吧。

先來看我圈出來的兩行代碼,源碼通過Object.defineProperty(target, key, sharedPropertyDefinition)來檢測vm對象的comouted中的key的變化。
再來看
const shouldCache = !isServerRendering()非服務器渲染環(huán)境下,需要緩存,這里就開始引出了,computed的特點來了,緩存

從源碼看,如果是需要緩存的話,還調用了createComputedGetter方法,接下來我們去找這個方法的定義。

源碼根據(jù)compued對象下的key值找到對應的watcher對象,然后判斷對象是否dirty
如果dirty了,那就是調用watcher.evaluate()方法
接下來有必要去翻翻watch類中具體實現(xiàn)了。
找到watcher.js
我先看到了這個dirty屬性。

可以看出來,這個dirty是和我們傳入的lazy相關,前面我們說到在實現(xiàn)化watcher的時候,默認傳入了{lazy:true}
所以第一次我們會調用 wather.evaluate()方法,我們再來看下evaluate方法的實現(xiàn)。

當dirty為true的時候,我們將get到的值賦給了this.也就是我們的wather對象的value屬性上,并且將我們的dirty設置為false,
也就是說在調用 createComputedGetter 函數(shù)的時候,當我們的watcher對象的dirty屬性為false的時候,就直接返回watcher對象的value屬性值。
dirty英文意思為臟的。也步是當數(shù)據(jù)有變化的時候,我們的computed屬性對就去做相應的get調用,否則直接返回wather實例上的value屬性
PS:了解angular1.x的童鞋可能知道,它里面的雙向數(shù)據(jù)綁定原理就是臟值檢查(dirtycheck)
總結:
computed中的key不能與data,props,methods中的key相同。在computed下的value值可以是一個函數(shù),也可以是一個對象,為對象的時候,必須得實現(xiàn)一個get對象(一般為方法)computed中的屬性可以直接綁定到模板字符串中。一般來說涉及到兩個data中的數(shù)據(jù)的相互計算的時候,我們使用計算屬性會比較合理。源碼中直接給computed對象中的key進行了數(shù)據(jù)綁定。這里是暢哥聊技術 《從源碼中學Vue》系列文章,更多精彩內容持續(xù)更新中,敬請期待。
未完待續(xù)。。。
掃描二維碼推送至手機訪問。
版權聲明:本文由財神資訊-領先的體育資訊互動媒體轉載發(fā)布,如需刪除請聯(lián)系。