不是那個五十道陰影,是說我也還沒看過。只是說,人在江湖跑,哪有不挨刀,總是要挨個幾刀才能算是大哥嘛(是嗎?
所以身為一個專業的菜蟲農夫,偶爾被鋤頭打到腳指頭也是很合理的(欸不對!
最近很流行作弊的表,剛好 vuex 也有一份,如果你沒看過,現在讓你看看(當然不是我整理的,網路上神人很多。
這表沒什麼大毛病,不過這樣的東西其實還是需要對 vuex 有相對程度的瞭解,看起來才會有些用處,不然對於初學者來說,她就只是一個整理得很漂亮的表單而已。
簡介
既然 vuex 稱做 state management pattern,那麼就表示我們是用他來存放並管理一些狀態,存放與取用的規則就不在贅述,官方有說明可以去看看(雖然不是正體中文
然後,我們來講講關於挨刀的部分。
陰影
- 嚴格模式下,所有狀態都必須透過 Mutations 來修改(這是規定
- Mutations 不能是非同步函示(這是規定
- 嚴格模式下,state 直接修改會被警告(請看 1.
- state 可以在應用程式宣告時操作
- 尚未初始化的 vuex 的任何 state 返回值大多都是
undefined
- 其他套件必須要在 plugins 內先同步(或是有特別的同步工具,例如 vuex-router-sync
- 非同步傳輸也要放在 plugins 先做,或是在應用程式宣告時做掉(例如登入檢查
- plugins 跑的東西在整個生命週期中,算很前面,但不代表你不會拿到
undefined
(詳見:Vuex 2.0 關於 plugins 的事情 - state 在任何組件(Components)中的任何一個生命週期階段,都有可能拿到
undefined
- state 在任何組件與嵌套組件 (Nested component) 中,__一定要__搭配
溫開水computed
才能確保每個組件的 state 是一致的 - 父組件做了
commit
或是dispatch
(通常是呼叫設定好的 actions 或是 mutations,不代表嵌套組件的 state 會馬上變更(請看 2. 與 10. - 任何的
commit
與dispatch
要小心與watch
組合成無窮迴圈 - 任何的組件
watch
還是會有機會拿到undefined
的 state(詳見:$watch 藏在原始碼裡的邊緣人 - vue-router 如果要拿到 vuex 的東西,請使用同步工具(請看 6.
- vue-router 生命週期當中,
before
開頭的會拿不到 state(或是拿到undefined
- vue-router 在應用程式宣告時,可以拿宣告好的 vuex 來操作,但規則同 1., 2., 3., 4.
- 遞迴組件(Recursive components)請謹慎使用 actions 或是 mutations(請看 12.
dispatch
雖比起commit
靈活,不過修改多值時請注意先後順序(後執行優先- 如果沒有特定目的,私心建議把簡單的
dispatch
挪到組件裡面,使用mapMutations
來直接操作commit
- 嵌套組件 (Nested component) 的
commit
如果同時執行,無法確保最終狀態(例如大家都在created
時 commit 了各自的數值 - 不要做 20. 這件蠢事,要做請呼叫父組件統一處理(例如使用
setTimeout
,clearTimeout
確保後執行優先 - 所有非同步函示請讓他離開 vuex,爾或是你在 Actions 內使用
Promise
或是await/async
(詳見:https://vuex.vuejs.org/en/actions.html 最底下有飯粒範例 - Actions 只能有__兩個__傳入參數(vuex 2.0 以後),亦即多參數只能透過 Object 的形式給第二個(詳見:https://github.com/vuejs/vuex/blob/dev/src/store.js#L357
- 雖然支援 Namespaced,但__用不好會下地獄__(當你有 modules 是
namespaced: true
,而有的不是的時候 - 當你沒打算使用 Namespaced 時,請注意所有東西的命名(預設全部綁在根組件上,所以名稱不可以重複
如果看到這邊還沒有放棄,那表示還有救。說好的 50 道陰影呢?
套路
要解決的套路很多,那就改天吧(欸!
首先,請對 vuex 能做的事情有一定程度的瞭解,再來思考你想要做的事情是否適合,或是是否有放到正確的位子上。
- 其他套件同步,除了第三方有提供的以外,可以使用 vuex 的 Plugins 來解套
computed
用於提取 state 是萬解,但是請把undefined
考慮進去- vue-router 的
before
系列,請把 vuex 的任何 state 預想為undefined
- vue-router 的
beforeEach
沒意外所有的 state 都是undefined
- 千萬不要
watch
相關 state 之後又去dispatch
或是commit
- 可以的話 Actions 盡量使用
Promise
或await/async
(因為潮 - Namespaced 可避免各種 modules 命名重複問題
- 如果使用 Namespaced 的話,那麼 Mutations 的名稱需要特別整理(請參考:https://vuex.vuejs.org/en/modules.html#namespacing
範例
我現在陰影有點多,暫時寫不出範例。