Vue computed 無法觸發原因
這篇是我自己踩雷後重新理解 computed 的筆記。以前會以為只要 computed 裡面有依賴的資料變了,它就一定會自動執行;但 Vue 的 computed 其實不是這樣工作的。
view 或者 methods 中有没有用到 pages,如果没有用到,那么是不会触发 computed 的
computed 的核心觀念
computed 本質上比較像是「帶快取的 getter」。它不是 watch,也不是事件監聽器,不會因為相依資料一改就主動做事;而是當畫面或程式真的去讀取這個 computed 屬性時,Vue 才會評估要不要重新計算。
所以最重要的一句話就是:
如果沒有地方使用到這個 computed,它就不會幫你執行。
為什麼會誤會
很多人第一次接觸 Vue,會把 computed 想成「資料變動時自動觸發邏輯」。但這其實比較接近 watch 的思維。
computed 比較像這樣:
- 有人讀取它。
- Vue 發現相依值改過。
- 重新執行 getter。
- 回傳新結果。
如果沒有第 1 步,後面根本不會發生。
最常見的踩雷場景
像下面這種寫法,很容易讓人以為 fullName 會自己跑:
|
|
但如果 template、method、其他 computed 都沒有用到 fullName,那這個 getter 不會被執行。
我這次踩雷的背景
我當時剛好搭配 monaco-editor 這類外部元件使用。它本身不是直接走 Vue 的 template/data binding 流程,而是比較偏事件驅動。結果我用事件改 Vue 的值,卻期待 computed 自己做後續動作,最後就卡了幾個小時。
這時才回頭理解,問題不是 Vue 沒偵測到資料,而是我根本沒有在 view 或 method 中真正使用到那個 computed 結果。
什麼時候該用 computed
我現在會這樣判斷:
- 只是把既有資料整理成「給畫面顯示」的結果,用 computed。
- 需要在資料變動時主動執行副作用,用 watch。
- 只是某個按鈕點下去才需要算一次,用 method。
這三個混掉就很容易寫出看似合理、實際卻不會動的程式。
如果是外部 JS 元件整合
如果你整合的是像 editor、地圖、圖表這類外部元件,我覺得比較實際的方向有:
- 在 method 中明確呼叫更新函式。
- 用 watch 監看資料後同步到外部元件。
- 把外部元件包成真正的 Vue 元件,讓資料流更一致。
我自己後來也覺得,這種情境單靠 computed 很常不夠直覺。