寫文章不容易,點個讚唄兄弟 專一 Vue 源碼分享,文章分爲白話版和 源碼版,白話版助於理解工做原理,源碼版助於瞭解內部詳情,讓咱們一塊兒學習吧 研究基於 Vue版本 【2.5.17】數組
若是你以爲排版難看,請點擊 下面連接 或者 拉到 下面關注公衆號也能夠吧緩存
今天咱們用白話文解讀 computed 的工做原理,輕鬆快速理解 computed 內部工做原理。由於若是你不懂原理,有時候作項目,碰到奇怪的問題,真的不知道怎麼回事性能
要理解 computed 的工做原理,只須要理解下面三個問題學習
一、computed 也是響應式的設計
二、computed 如何控制緩存blog
三、依賴的 data 改變了,computed 如何更新圖片
開始咱們今天的講解,但願你認真看完會有收穫get
"必須有收穫謝謝,否則我不白寫了嗎兄弟"源碼
在這裏,我先告訴你,computed 實際上是一個 月老,專門牽線
<br> <br>
什麼是響應式,不知道的童鞋請參考我之前的文章
你給 computed 設置的 get 和 set 函數,會跟 Object.defineProperty 關聯起來
因此 Vue 能捕捉到 讀取computed 和 賦值computed 的操做
讀取computed 時,會執行你設置的 get 函數,可是並無這麼簡單,由於還有一層緩存的操做
賦值 computed 時,會執行你設置的 set 函數,這個就比較簡單,會直接把 set 賦值給 Object.defineProperty - set
<br> <br>
咱們都知道,computed 是有緩存的,官方已經說明
"計算屬性是基於它們的依賴進行緩存的。計算屬性只有在它的相關依賴發生改變時纔會從新求值"
"咱們爲何須要緩存?假設咱們有一個性能開銷比較大的計算屬性 A,它須要遍歷一個巨大的數組並作大量的計算。而後咱們可能有其餘的計算屬性依賴於 A 。若是沒有緩存,咱們將不可避免的屢次執行 A 的 getter"
如今咱們要開始講解,Computed 是如何判斷是否使用緩存的
首先 computed 計算後,會把計算獲得的值保存到一個變量中。讀取 computed 時便直接返回這個變量。
當使用緩存時,就直接返回這個變量。當 computed 更新時,就會從新賦值更新這個變量
computed 控制緩存的重要一點是 【髒數據標誌位 dirty】,dirty 是 watcher 的一個屬性
當 dirty 爲 true 時,讀取 computed 會從新計算
當 dirty 爲 false 時,讀取 computed 會使用緩存
1一開始每一個 computed 新建本身的watcher時,會設置 watcher.dirty = true,以便於computed 被使用時,會計算獲得值
2當 依賴的數據變化了,通知 computed 時,會設置 watcher.dirty = true,以便於其餘地方從新渲染,從而從新讀取 computed 時,此時 computed 從新計算
3computed 計算完成以後,會設置 watcher.dirty = false,以便於其餘地方再次讀取時,使用緩存,免於計算
<br> <br>
首先,data 和 computed 本質上差很少,都是數據,都須要被使用。
當 A 引用 B 的時候,B 會收集 A 的watcher,不明白的能夠參考以前文章
【Vue原理】響應式原理 - 白話版
如今 頁面A 引用了 computed B,computed B 依賴了 data C
像是這樣,A->B->C 的依賴順序
一開始個人想法是,data C 開始變化後.......
1通知 computed B 更新,而後 computed B 開始從新計算
2接着 computed B 通知 頁面A更新,而後從新讀取 computed
一條鏈式的操做? C -》 B -》 A 這樣的執行順序嗎?
答案:不是
其實真正的流程是,data C 開始變化後.......
1通知 computed B watcher 更新,其實只會重置 髒數據標誌位 dirty =true,不會計算值
2通知 頁面 A watcher 進行更新渲染,進而從新讀取 computed B ,而後 computed B 開始從新計算
data C 的依賴收集器會同時收集到 computed B 和 頁面 A 的 watcher
這就是 Vue 設計的巧妙之處了,也就是我開始講的,computed 實際上是一個 月老
在 頁面 A 在讀取 computed B 的時候,趁機把 頁面A 介紹給 data C ,因而 頁面A watcher 和 data C 間接牽在了一塊兒,因而 data C 就會收集到 頁面A watcher
至於怎麼牽在一塊兒,白話版不會多說,不浪費你們的腦力
被依賴通知更新後,重置 髒數據標誌位 ,頁面讀取 computed 時再更新值
<br> <br>
1computed 經過 watcher.dirty 控制是否讀取緩存
2computed 會讓 【data依賴】 收集到 【依賴computed的watcher】,從而 data 變化時,會同時通知 computed 和 依賴computed的地方