# Module
# 分割
將 store
分割成 module
,每個 module
擁有自己的 state
、mutation
、action
、getter
。
const moduleA = {
namespaced: true,
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
moduleA,
moduleB
}
})
store.state.moduleA // -> moduleA 的state狀態
store.state.moduleB // -> moduleB 的state狀態
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 作用域
module
內部的 mutation
和 getter
,接收的第一個參數為 Module
作用域物件。
const moduleA = {
namespaced: true,
// count 會寫到全域
// 取用方法: $store.state.moduleA.count
state: { count: 0 },
mutations: {
increment(state) {
// state: Module 作用域物件
state.count++;
},
},
getters: {
// 取用方法: $store.getters.moduleA.doubleCount
// 或: $store.rootGetters.doubleCount
doubleCount(state) {
return state.count * 2;
},
},
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
action
同樣也是使用 Module
作用域物件。
const moduleA = {
// ...
actions: {
// state: 作用域狀態
// rootState: 根節點、子節點的 state 資料
// rootGetters: 根節點、子節點的 getters 資料
actionIncrement({ state, dispatch, commit, rootState, rootGetters }) {
if ((state.count + rootState.count) % 2 === 1) {
commit('increment');
}
},
},
};
2
3
4
5
6
7
8
9
10
11
12
13
# 命名空間
默認情況下,模組內部的 action
、mutation
和 getter
是註冊在 全域 的命名空間。
這樣使得多個模組能夠對同一 mutation
或 action
作出響應。
通過添加 namespaced: true
的方式使其成為帶命名空間的模組。
當模組被註冊後,它的所有 getter
、action
及 mutation
都會自動根據 模組註冊的路徑 調整命名。
# 範例
const store = new Vuex.Store({
modules: {
account: {
namespaced: true,
// 模組內容(module assets)
// 模組內的狀態已經是嵌套的了,使用 namespaced 屬性不會對其產生影響
state: { ... },
getters: {
isAdmin () { ... } // -> getters['account/isAdmin']
},
actions: {
login () { ... } // -> dispatch('account/login')
},
mutations: {
login () { ... } // -> commit('account/login')
},
// 嵌套模組
modules: {
// 繼承父模組的命名空間
myPage: {
state: { ... },
getters: {
profile () { ... } // -> getters['account/profile']
}
},
// 進一步嵌套命名空間
posts: {
namespaced: true,
state: { ... },
getters: {
popular () { ... } // -> getters['account/posts/popular']
}
}
}
}
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
在 mapActions
,mapMutations
與 mapGetters
中皆需也使用模組的註冊名稱作為呼叫的路徑。
import { mapGetters } from 'vuex';
export default {
name: 'MyComponent',
computed: {
...mapGetters({
getAAge: 'a/getAAge',
getBAge: 'getBAge',
}),
},
};
2
3
4
5
6
7
8
9
10
11
# 命名空間的綁定函數
使用 mapState
、mapGetters
、mapActions
和 mapMutations
。
可以通過使用 createNamespacedHelpers
創建基於某個命名空間輔助函數。
可用於找 自身和其他模組 的
state
// 注意這一段
import { createNamespacedHelpers } from 'vuex';
const { mapState, mapActions } = createNamespacedHelpers('some/nested/module');
export default {
computed: {
// 在 `some/nested/module` 中查找
...mapState({
a: (state) => state.a,
b: (state) => state.b,
}),
...mapGetters({
getAAge: 'getAge',
}),
},
methods: {
// 在 `some/nested/module` 中查找
...mapActions(['foo', 'bar']),
},
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 第三個參數
在 namespaced: true
下,commit
和 dispatch
的第三個參數可以指定 { root: true }
,表示從 Vuex 根元件 呼叫一個方法,他可以根據 Module 的設定來 戳 到指定的目標。
store.commit('a/other/module', {}, { root: true });
store.dispatch('a/other/module', {}, { root: true });
2
使用情境:在本身的 Module 中,需要去呼叫其他 Module 的時候,必須要加上這個參數,這樣才能觸發到想要的目標。不然依照 namespaced: true
的設定,在 Module 裡面的 commit
都是觸發本地端 (Local state) 的方法 (包括 commit
或是 dispatch
)。
所以,Module 是 namespaced: true
的話,第三個參數沒有設定,就會被回報錯誤。