Vue.js 計算屬性的祕密

      計算屬性是一個很邪門的東西,只要在它的函數裏引用了 data 中的某個屬性,當這個屬性發生變化時,函數彷彿能夠嗅探到這個變化,並自動從新執行。html

      上述代碼會源源不斷的打印出 b 的值。若是但願 a 依賴 data 中的 x 而變化,只需保證 a 函數中有 this.x 便可。若是函數中沒有出現 data 中的屬性,那麼不管 data 中的屬性怎麼變,a 對應的函數一次也不會執行。vue

      Vue 怎麼知道計算屬性在函數中引用了哪一個 data 屬性?這個函數又是怎麼知道 data 屬性變了,並且只關心它內部引用的那個屬性,別的都無論?閉包

      官方文檔對計算屬性的描述是:函數

      文檔的描述讓個人困惑更加困惑,還有這種操做?這特麼是怎麼作到的?測試

      Google 了一把,看了一篇三哥的博文(見文末),豁然開朗。this

      咱們簡單模擬實現一個計算屬性:a 變化時,b 自動跟着變化。spa

      因爲涉及 Vue 的響應式綁定的原理,若是你對此不熟,最好先看看《Vue.js 雙向綁定的實現原理》
雙向綁定

      少囉嗦,先看過程:htm

      1. 首先 b 屬性會被處理爲存取器屬性,訪問 b 就會觸發其 get 函數blog

      2. 處理計算屬性 a 時,會執行 a 的函數,從而會執行 this.b,因而觸發 b 的 get 函數

      3. b 的 get 函數會添加 b 屬性的依賴項,而剛纔在處理計算屬性過程當中,a 已經做爲依賴項被傳給了一個全局變量,b 的 get 函數會檢測到這個全局變量,並將其添加到自身的訂閱者列表中

      4. 對 b 賦予新的值時,會觸發其 set 函數,set 函數中會遍歷執行訂閱者,a 的值就是在這個時候更新的

      再看代碼:

(注:圖中數字僅做思路引導,並不是與前文過程描述對應)

      測試一下,完美打印出 1, 2, 3, 4

      console.log(obj.b)

      obj.a += 1;

      console.log(obj.b);

      obj.a += 1;

      console.log(obj.b);

      obj.a += 1;

      console.log(obj.b);

     

      經過對存取器屬性、閉包和觀察者模式的綜合運用,Vue 巧妙的實現了計算屬性。如今再看官方文檔描述,是否是更通透了呢。

      能夠看出,Vue 響應式系統的核心理念是「依賴」,DOM 節點之因此隨數據而變化,是由於節點依賴於數據,計算屬性之因此隨數據而變化,是由於計算屬性依賴於數據。作好響應式的關鍵就在於處理好依賴關係。

 

參考文章:https://skyronic.com/blog/vuejs-internals-computed-properties

相關文章
相關標籤/搜索