1. はじめに
先日以下の記事を書く中で疑問に思った点がありました。
それは、context オブジェクトのプロパティを調べる中で登場したrootGetters
やrootState
です。
「rootStateはモジュール内からルートのstateにアクセスするために使用される」
と理解したものの、モジュールとルートの関係性を理解できていなかったので、この記事ではモジュールという概念についてまとめます。
2. モジュールとは
モジュールはストアを機能単位・役割単位に分割したものです。
各モジュールは独自に state, mutations, actions, getters を持つことができます。
ストアとはVueアプリケーション全体の状態・ロジックなどを一元管理する “中枢”
以下の例では、ストアをモジュールAとモジュールBに分けています。
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = createStore({
modules: {
a: moduleA,
b: moduleB
}
})
3. 名前空間(namespace)
モジュールには名前空間という考え方があります。
これは、Vuexモジュールの中の state・mutations・actions・getters にスコープを持たせる仕組みで、名前空間があることにより、他のモジュールと名前が衝突しないようになります。
名前空間がなぜ必要かというと、
Vuexはデフォルトではすべての mutations, actions, getters をグローバルに登録するからです。
例えば以下のようなモジュールがあった場合、どちらのsetUser()
もグローバルに登録されてしまい、両者の区別がつかなくなります。
const moduleA = {
mutations: {
setUser() {}
}
}
const moduleB = {
mutations: {
setUser() {}
}
}
ここでnamespaced: true
を使用することで、moduleAのsetUser()、moduleBのsetUser()というように区別できるようになります。
const moduleA = {
namespaced: true,
state: () => ({
user: null
}),
mutations: {
setUser(state, user) {
state.user = user
}
}
}
const moduleB = {
namespaced: true,
state: () => ({
user: null
}),
mutations: {
setUser(state, user) {
state.user = user
}
}
}
const store = createStore({
modules: {
a: moduleA,
b: moduleB
}
})
// moduleA の setUser を呼び出す
store.commit('a/setUser', { name: 'Taro from A' })
// moduleB の setUser を呼び出す
store.commit('b/setUser', { name: 'Jiro from B' })
4. rootGettersとrootStateを使用する場面
ここで、この記事のはじめに触れた
「rootStateはモジュール内からルートのstateにアクセスするために使用される」
の意味が理解できるようになりました。
モジュールは名前空間(namespaced: true)によって限られたスコープに閉じられているため、別のモジュールのstateやgettersを使用したいときは、rootState
やrootGetters
を使用します。
・gettersの引数として使用される場合
getterの引数として使用されるとき、rootState, rootGetters が第3引数・第4引数として渡されます。
someGetter (state, getters, rootState, rootGetters){ (略) }
・actionsの引数として使用される場合
actionsが引数にとるcontext オブジェクトのプロパティにはrootGettersとrootStateが含まれているので、これを使用することができます。
他モジュールのactionやmutationを使用したいときは、dispatchとcommitの3番目の引数として {root: true}
を渡します。
dispatch('someAction', null, { root: true })
commit('someMutation', null, { root: true })
5. 最後に
モジュール、ルート、グローバル...といった普段見聞きする単語も、いざアウトプットしようとすると理解していなかったことに気づかされました。
これらの概念は、Vuexに限らずさまざまな領域に適用されるものだと思うので、丁寧に理解していきたいです。
最後までお読みいただきありがとうございました!
参考