/ VueJS

[VueJS] vuex 的五十道陰影

不是那個五十道陰影,是說我也還沒看過。只是說,人在江湖跑,哪有不挨刀,總是要挨個幾刀才能算是大哥嘛(是嗎?

所以身為一個專業的菜蟲農夫,偶爾被鋤頭打到腳指頭也是很合理的(欸不對!


最近很流行作弊的表,剛好 vuex 也有一份,如果你沒看過,現在讓你看看(當然不是我整理的,網路上神人很多。

https://vuejs-tips.github.io/vuex-cheatsheet/

這表沒什麼大毛病,不過這樣的東西其實還是需要對 vuex 有相對程度的瞭解,看起來才會有些用處,不然對於初學者來說,她就只是一個整理得很漂亮的表單而已。

簡介

既然 vuex 稱做 state management pattern,那麼就表示我們是用他來存放並管理一些狀態,存放與取用的規則就不在贅述,官方有說明可以去看看(雖然不是正體中文

https://vuex.vuejs.org/zh-cn/intro.html

然後,我們來講講關於挨刀的部分。

陰影

  1. 所有狀態都必須透過 Mutations 來修改(這是規定
  2. Mutations 不能是非同步函示(這是規定
  3. state 直接修改會被警告(請看 1.
  4. state 可以在應用程式宣告時操作
  5. 尚未初始化的 vuex 的任何 state 返回值大多都是 undefined
  6. 其他套件必須要在 plugins 內先同步(或是有特別的同步工具,例如 vuex-router-sync
  7. 非同步傳輸也要放在 plugins 先做,或是在應用程式宣告時做掉(例如登入檢查
  8. plugins 跑的東西在整個生命週期中,算很前面,但不代表你不會拿到 undefined(詳見:Vuex 2.0 關於 plugins 的事情
  9. state 在任何組件(Components)中的任何一個生命週期階段,都有可能拿到 undefined
  10. state 在任何組件與嵌套組件 (Nested component) 中,__一定要__搭配溫開水 computed 才能確保每個組件的 state 是一致的
  11. 父組件做了 commit 或是 dispatch(通常是呼叫設定好的 actions 或是 mutations,不代表嵌套組件的 state 會馬上變更(請看 2. 與 10.
  12. 任何的 commitdispatch 要小心與 watch 組合成無窮迴圈
  13. 任何的組件 watch 還是會有機會拿到 undefined 的 state(詳見:$watch 藏在原始碼裡的邊緣人
  14. vue-router 如果要拿到 vuex 的東西,請使用同步工具(請看 6.
  15. vue-router 生命週期當中,before 開頭的會拿不到 state(或是拿到 undefined
  16. vue-router 在應用程式宣告時,可以拿宣告好的 vuex 來操作,但規則同 1., 2., 3., 4.
  17. 遞迴組件(Recursive components)請謹慎使用 actions 或是 mutations(請看 12.
  18. dispatch 雖比起 commit 靈活,不過修改多值時請注意先後順序(後執行優先
  19. 如果沒有特定目的,私心建議把簡單的 dispatch 挪到組件裡面,使用 mapMutations 來直接操作 commit
  20. 嵌套組件 (Nested component)commit 如果同時執行,無法確保最終狀態(例如大家都在 created 時 commit 了各自的數值
  21. 不要做 20. 這件蠢事,要做請呼叫父組件統一處理(例如使用 setTimeout, clearTimeout 確保後執行優先
  22. 所有非同步函示請讓他離開 vuex,爾或是你在 Actions 內使用 Promise 或是 await/async(詳見:https://vuex.vuejs.org/en/actions.html 最底下有飯粒範例
  23. Actions 只能有__兩個__傳入參數(vuex 2.0 以後),亦即多參數只能透過 Object 的形式給第二個(詳見:https://github.com/vuejs/vuex/blob/dev/src/store.js#L357
  24. 雖然支援 Namespaced,但__用不好會下地獄__(當你有 modules 是 namespaced: true,而有的不是的時候
  25. 當你沒打算使用 Namespaced 時,請注意所有東西的命名(預設全部綁在根組件上,所以名稱不可以重複

如果看到這邊還沒有放棄,那表示還有救。說好的 50 道陰影呢?

套路

要解決的套路很多,那就改天吧(欸!

首先,請對 vuex 能做的事情有一定程度的瞭解,再來思考你想要做的事情是否適合,或是是否有放到正確的位子上。

  1. 其他套件同步,除了第三方有提供的以外,可以使用 vuex 的 Plugins 來解套
  2. computed 用於提取 state 是萬解,但是請把 undefined 考慮進去
  3. vue-router 的 before 系列,請把 vuex 的任何 state 預想為 undefined
  4. vue-router 的 beforeEach 沒意外所有的 state 都是 undefined
  5. 千萬不要 watch 相關 state 之後又去 dispatch 或是 commit
  6. 可以的話 Actions 盡量使用 Promiseawait/async(因為潮
  7. Namespaced 可避免各種 modules 命名重複問題
  8. 如果使用 Namespaced 的話,那麼 Mutations 的名稱需要特別整理(請參考:https://vuex.vuejs.org/en/modules.html#namespacing

範例

我現在陰影有點多,暫時寫不出範例。