2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Vuex】モジュールとルートの関係

Posted at

1. はじめに

先日以下の記事を書く中で疑問に思った点がありました。
それは、context オブジェクトのプロパティを調べる中で登場したrootGettersrootStateです。

「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を使用したいときは、rootStaterootGettersを使用します。

・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に限らずさまざまな領域に適用されるものだと思うので、丁寧に理解していきたいです。

最後までお読みいただきありがとうございました!

参考

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?