當前位置:編程學習大全網 - 源碼下載 - Vue3.0采用新特性Proxy來實現數據狀態的響應,它的原理是什麽?

Vue3.0采用新特性Proxy來實現數據狀態的響應,它的原理是什麽?

Vue3 使用了 Proxy 替換了原來的 Object.defineProperty 來實現數據響應。

很簡單,直接Vue引入reactive方法,接收壹個對象參數,就實現了數據的響應式:

reactive 內部的核心代碼 簡化 如下:

首先判斷傳入的參數類型是否可以用於觀察,目前支持的類型為 Object|Array|Map|Set|WeakMap|WeakSet。

接下來判斷參數的構造函數,根據類型獲得不同的 handlers。這裏我們就統壹使用 baseHandlers ,因為這個已經覆蓋 99% 的情況了。只有 Set, Map, WeakMap, WeakSet 才會使用到 collectionHandlers。

對於 baseHandlers 來說,最主要的是劫持了 get 和 set 行為,這兩個行為同時也能原生劫持 數組下標修改值及對象新增屬性的行為, 這壹點非常重要,因為 Object.defineProperty 就不行。

最後就是構造壹個 Proxy 對象完成數據的響應式。相比 Object.defineproperty 壹開始就要 遞歸遍歷整個對象 的做法來說,使用 Proxy 性能會好得多。比如原來 forEach 遍歷:

接下來當我們去使用 state 對象的時候,就能劫持到內部的行為。

讀取時:state.num 就會觸發 get 函數;

修改時:state.num = 100 就會觸發 set 函數。

以下是這兩個函數的核心(TS語法):

對於 get 函數來說,獲取值肯定是最核心的壹步驟了。接下來是調用 track,這個和 effect 有關,下文再說。最後是判斷值的類型,如果是對象的話就繼續包裝成 Proxy。

對於 set 函數來說,設置值是第壹步驟,然後調用 trigger,這也是 effect 中的內容。

簡單來說,如果某個 effect 回調中有使用到 state.num,那麽這個回調會被收集起來,並在調用 state.num =100 時觸發。

那麽怎麽收集這些內容呢?這就要說說 targetMap 這個對象了。它用於存儲依賴關系,類似以下結構,這個結構會在 effect 文件中被用到

先來解釋下三者到底是什麽,這個很重要

這裏筆者把這些內容脫離源碼串起來講壹下流程。

首先創建壹個 Proxy 對象,targetMap 會把這個對象收集起來當做 key。

接下來調用 effect 回調的時候會把這個回調保存起來,用於下面的依賴收集。在調用的過程中會觸發 counter 的 get 函數,內部調用了 track 函數,這個函數會使用到 targetMap。

這裏首先通過 target 從 targetMap 中取到壹個對象,這個對象也就是 target 所有的依賴關系。那麽對於 counter.num 來說,num 就是這個對象的 key(這裏如果有點模糊的話可以先看下上面的數據結構),值是壹個依賴回調的集合,因為 counter.num 可能會被多個地方依賴到。

回調執行完畢以後會把保存的回調銷毀掉。

當我們調用 counter.num = 7 時,觸發 set 函數,內部調用 trigger 函數,同樣會使用到 targetMap。

同樣通過 target 取到壹個對象,然後通過 key 也就是 num 去取出依賴集合,最後遍歷這個集合執行裏面所有的回調函數。

另外對於 computed 來說,內部也是使用到了 effect,無非它的回調不會在調用 effect 後立即執行,只有當觸發 get 行為以後才會執行回調並進行依賴收集,舉個例子:

對於以上代碼來說,computed 的回調永遠不會執行,只有當使用到了 cValue.value 時才會執行回調,然後接下來的操作就和上面的沒區別了。

  • 上一篇:android中git是做什麽用的
  • 下一篇:開發壹個類似LOL視頻直播APP需要多少錢,誰可以給個APP報價單?
  • copyright 2024編程學習大全網