前端必讀:Vue響應式系統大PK(下)

轉載請註明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者。
原文參考://www.sitepoint.com/vue-3-reactivity-system/

在上節中我們對Vue2和Vue3中的響應式系統做了對比,帶大家了解了響應式系統的工作原理,今天我們來進一步探索Vue3中的響應式系統API,為了讓大家更好的理解和學習,將方法分組進行歸納。

基本方法

第一組

包括控制數據響應的最基本方法

  • ref接受一個原始值或一個普通對象,然後返回一個響應且可變的ref對象。ref對象只有一個value指向原始值或純對象的屬性。
  • reactive接收一個對象並返回該對象的反應性副本,該內容會影響所有嵌套屬性。
  • readonly接受一個ref或一個對象(plain 或reactive),並將一個只讀對象返回給原始對象,且會影響所有嵌套屬性。
  • markRaw 返回對象本身,並防止將其轉換為代理對象。

實際使用

2.png

微信截圖_20210519155131.png

在此示例中,我們探索了四種基本響應式方法的使用。

1.創建一個counterref對象,其值為0。然後在視圖中放置兩個按鈕,用於增加和減少計數器的值。當使用發現計數器沒有作用。

2.其次創建一個person響應對象。在視圖中放置兩個輸入控件,分別用於編輯一個人的name和一個人的age。當我們編輯人員的屬性時會立即更新。

3.創建一個math只讀對象。然後在視圖中設置一個按鈕,用於將math的PI屬性值加倍。該對象只可讀,不可修改。

4.創建一個alphabetNumbers對象,將其標記為raw。取其前三位內容。設置一個按鈕,將Bproperty的值更改為3。我們會發現可以修改對象,但不會導致視圖重新渲染。

markRaw 方法非常適合我們不需要響應的對象,例如一長串國家/地區代碼,顏色名稱及其對應的十六進制數字,等等。

5.測試和確定我們創建的每個對象的類型,使用onMounted()的生命周期鉤子(lifecycle hook)觸發這些檢查。

類型檢查方法

該組包含上述所有四個類型檢查器:

  • isRef 檢查值是否是引用對象
  • isReactive檢查對象是是由reactive創建還是readonly通過包裝由創建的另一個代理而創建的反應代理reactive
  • isReadonly檢查對象是否是由創建的只讀代理readonly
  • isProxy檢查對象是否是由reactive或創建的代理readonly

更多參考方法

該組包含其他引用方法:

  • unref 返回引用的值
  • triggerRef執行與shallowRef手動相關的任何效果
  • customRef 創建具有自定義引用的顯式控件,並對其依賴項跟蹤進行顯式控制並更新觸發

淺層方法

該組中的方法是ref,reactivity和readonly:

  • shallowRef創建一個ref,該ref僅跟蹤其value屬性而不會使其值具有響應性
  • shallowReactive 創建一個響應式代理,該代理僅跟蹤其自身的屬性(不包括嵌套對象)
  • shallowReadonly 創建一個只讀代理,該代理僅使自己的屬性變為只讀(不包括嵌套對象)

通過以下示例來感受這些方法的使用:

3.png

4.png
本示例從創建settings淺引用對象開始,在視圖中添加兩個輸入控件以編輯其width和height屬性。但該屬性卻不能修改,為了解決這個問題,添加一個按鈕,該按鈕可以更改整個對象及其所有屬性。

接着創建一個settingsA淺層反應式代理,包含width和height屬性,和帶有x和y屬性的嵌套對象coords。在視圖中為每個屬性設置一個輸入控件。修改width和height屬性時,有響應更新,但是修改x和y屬性時卻沒有變化。

最後創建一個settingsB淺層只讀對象,屬性與settingsA相同。但此處widthorheight屬性只可讀,不能修改,x和y屬性可以正常修改。

最後兩個示例中的嵌套對象coords均不受轉換的影響, Vue不會跟蹤它的任何修改,可以自由修改。

轉換方式

接下來的三種方法用於將代理轉換為ref或普通對象:

  • toRef為源響應對象上的屬性創建一個引用。引用將響應性連接保持到其源屬性。
  • toRefs將響應對象轉換為普通對象。普通對象的每個屬性都是一個指向原始對象相應屬性的ref。
  • toRaw返回areactive或readonlyproxy的原始對象。

在下面的示例中,將展示這些轉換是如何工作:

5.png

6.png
在此示例中
1.創建一個基礎person反應對象,並將其用作源對象。

2.將name property轉換為具有相同名稱的ref。在視圖中添加兩個輸入控件-一個用於name引用,另一個用於nameproperty。當其中一個被修改,另一個也會更新。

3.將其中一個人所有屬性轉換為personDetails對象中包含的各個引用。在視圖中再次添加兩個輸入控件以測試剛剛創建的引用之一。發現personDetailsage與人的age屬性完全同步。

4.將person響應性對象轉換為rawPerson普通對象。在視圖中添加一個輸入控件以編輯rawPerson的hobby屬性,Vue並不進行跟蹤。

計算和監視方法

最後一組方法用於計算複雜值並監控某些值:

  • computed 以getter函數作為參數,並返回一個不變的響應式ref對象。
  • watchEffect 立即運行一個函數,並以響應方式跟蹤其依賴關係,並在依賴關係發生更改時重新運行它。
  • watch與Options API this.$watch和相應的watch選項完全等效。它監視特定的數據源,並在監視的源發生更改時在回調函數中施加副作用。

我們繼續看看以下示例:

7.png

8.png
在此示例中,我們創建了一個fullName計算變量,該變量的計算基於firstName和lastName。在視圖中添加了兩個輸入控件,用於編輯全名的兩個部分。修改任何部分fullName都會重新計算並更新結果。

接下來,我們創建一個volumeref並為其設置觀看效果,每次volume修改後都將運行回調函數。為了驗證流程是否這樣,我們在視圖中添加一個按鈕,該按鈕將音量增加一倍。接着在回調函數中設置一個條件,以測試該音量的值是否可以分為分成三份,當它返回true時,將顯示一條警報消息。

最後,我們創建一個stateref並設置一個watch函數來跟蹤它的更改。state改變執行函數。此外我們添加了一個按鈕,用於在playing和paused之間切換狀態。狀態發生切換,則有提示。

watchEffect與watch一些區別:

  • watchEffect將回調函數中包含的所有響應性屬性視為依賴項。因此,如果回調包含三個屬性,則會隱式跟蹤所有屬性的更改。
  • watch僅跟蹤我們作為回調參數包含的屬性。此外,它還提供了watched屬性的先前值和當前值。

我們會發現,Vue 3響應式API為各種用例提供了許多方法,API內容很多,在本教程中我們僅探討了基礎知識。有關更深入的探索,詳細信息和邊緣案例,請訪問Reactivity API文檔。

結論

在本文中,我們介紹了什麼是響應系統以及如何在Vue 2和Vue 3中實現該系統。一些Vue 2具的缺陷已經在Vue3中被很好的解決。最後讓我們總結一下Vue3響應式系統的優缺點。

好處

  • 可以用作獨立程序包。例如,您可以將其與React一起使用
  • 憑藉其功能豐富的API,可以實現很多功能,靈活性很高
  • 支持更多的數據結構(Map,WeakMap,Set,WeakSet)
  • 具有更好的性能,僅使所需的數據具有響應性
  • 解決了Vue 2中的數據操作警告

缺點

  • 僅適用於支持ES6 +的瀏覽器
  • 在比較(===)方面,響應式代理不等於原始對象
  • 與Vue 2「自動」反應性相比,需要更多的代碼