Vue 提供了三個 Reactivity API:computed()
、watch()
與 watchEffect()
,三者很類似,但又不完全相同。
Version
Vue 3.4
Behavior
computed()
:一開始會執行一次watch()
:一開始不執行,追蹤的 state 改變才會執行watchEffect()
:一開始會執行一次
Parameter
computed()
:不可傳參數,若要傳參數改用一般 functionwatch()
:可傳參數,第一個參數為newValue
,第二個參數為oldValue
watchEffect()
:不可傳參數
Sychoronous / Asynchronous
computed()
:只能同步
(不能 call API)watch()
:同步
、非同步
皆可watchEffect()
:同步
、非同步
皆可
Side Effect
computed()
:不可處理 Side Effect (Pure Function)watch()
:專門處理 Side EffectwatchEffect()
:專門處理 Side Effect
Return
computed()
:回傳結果watch()
:無回傳結果,執行傳入 functionwatchEffect()
:無回傳結果,執行傳入 function
Tracking Target
computed()
:可追蹤 state、computedwatch()
:可追蹤 state、computed 或 arraywatchEffect()
:可追蹤 function 內同步
的 state、computed 或 array,但不追蹤非同步
的 state、computed 或 array
Effeciency
computed()
:支援 cachewatch()
:不支援 cachewatchEffect()
:不支援 cache
Maintainability
computed()
:可在 HTML template 中直接發現 computed 被使用,然後一直 trace function 即可,容易 debugwatch()
:常會沒發現原來有個 state 或 computed 被 watch 偷偷修改,因為在 trace function 時無法發現有watch()
存在,不容易 debugwatchEffect()
:常會沒發現原來有個 state 或 computed 被 watch 偷偷修改,因為在 trace function 時無法發現有watchEffect()
存在,不容易 debug
Usage
computed()
:90%
盡量使用 computed 實現watch()
:5%
僅用於 edge case、特例或 computed 難以實現時watchEffect()
:5%
僅用於 edge case、特例 或 computed 難以實現時
Conclusion
computed()
:適合單純用來加工資料,如 HTML Template 上的顯示,watch()
:追蹤單一 state,且傳入 function 想根據新舊資料進行處理,如 route 參數變化重新發 APIwatchEffect()
:追蹤多個 state,且一開始會執行一次,如輸入變化會重新發 API,但有提供預設值可先執行一次- 有些需求用
computed()
、watch()
與watchEffect()
都可實現時,優先使用computed()
,這是效率最好的方式,也是可讀性最高,最容易維護方式, 而watch()
與watchEffect()
常常會讓人忽略原來還有代碼寫在這裡