這系列到目前為止,其實已經把 Vuex 基本的使用方式介紹得差不多了。
而本篇則是會介紹一些比之前進階一點的寫法,也就是將 Vuex 中管理的資料模組化,並以與之前不同的形式在元件中讀取資料。
Vuex 中的 getters, mapGetters, mapActions
這一段要介紹的是:在元件中提取 Vuex 函式的新方法。
- 在 store 中加上
getters
物件,把在元件中要用computed
呈現在畫面上的資料移進來。移進來的形式是 function 形式,且帶入跟mutations
一樣的參數(state
)。
1 | getters: { |
- 到要呈現畫面的元件中(Home.app),引入 Vuex 中的
mapGetters
,注意,要用物件包住要引入項目。
1 | import { mapGetters } from 'vuex'; |
- 移除原本
computed
中定義的資料函式,改用展開符號把mapGetters
的內容取出來,並指定要取出裡面的哪些 gettets。
1 | computed: { |
- 除了
mutations
可以改成getters
,actions
也能用這種方法,從 store 取出來用在元件上。首先在引入的地方,多增加mapActions
的引入。
1 | import { mapGetters, mapActions } from 'vuex'; |
mapActions
可以用來替換元件中不需要帶入參數的methods
函式,例如以下這樣:
1 | // 原本是這樣 |
補充說明:mapActions 的使用時機
mapActions
的使用時機,最簡單的辨別方式就是「需不需要帶入參數」,若需要就不能使用 mapActions
。
模組化資料運用
場景從元件切回到 store。
接下來我們要把 store 中的程式碼再做拆分(模組化),例如,將行為及資料分為兩大類:「取得產品」類及「取得購物車、新增刪除品項」類。
以下以「取得產品」類為例,示範如何將資料模組化。
在 store 資料夾新增 products.js
在裡面寫好
export default {}
後就可以複製 store 中的程式碼,移到這個物件裡。但因為這個檔案只放與產品相關的行為,所以跟購物車、讀取效果有關的程式碼就先移除。把 axios import 進來
回到 store/index.js,把已經拆出去的程式碼刪掉,然後引入 products.js,並且幫 products.js 取一個模組名稱叫做
productsModules
。
1 | import productsModules from './products'; |
- 一樣是在 index.js 中,在
getter
物件下方新增modules
物件,在裡面直接貼入modules
名稱。
1 | modules: { |
模組重要概念
在 products.js 中,state
是模組內的區域變數,除此以外 actions
、mutations
、getters
等都是全域變數。
所以如果 store 中有其他模組使用與 products.js 相同名稱的 actions
、mutations
、getters
,就會出現錯誤。
如果在元件中想要讀取模組的 state
變數,要這樣寫:
1 | console.log(this.$store.state.productsModules.products); |
如果希望
actions
、mutations
、getters
都變成模組內的區域變數,該怎麼做?
只要在 state
上一行加上 namespaced: true
,它們就都會變成區域變數了,但此時元件就沒辦法直接讀到這些行為。
解決方法是,當使用 mapGetters()
時,也把模組名稱帶進來:
1 | ...mapGetters('productsModules', ['categories', 'products']); |
不過,當元件內同時要讀取模組資料及全域資料時,就要標示出哪些是全域資料,標示的方法是在 commit()
中帶入 { root: true }
當參數:
1 | // LOADING 是定義在 index.js 中的全域變數 |
Vuex 筆記到此差不多告一個段落了~
這些筆記都是我在上六角學院的 Vue.js 課程中寫下的筆記,不過我可能還是有寫得不夠仔細的地方,
所以附上兩個我覺得整理得很不錯的文章給各位一起參考: