【Vue.js】Vuexで他のモジュールのアクションを呼び出す【メモ】

Vue.js logo
ストアオブジェクトを複数のモジュールに分けていた場合に、1つのモジュールから他のモジュールのアクションを呼び出した方が効率的ということがあります。それぞれ名前空間が決まってるわけだし、呼び出すことは出来ないんじゃないか……と思ってたんですけど、普通に出来るみたいですね。


公式ドキュメントの中にこんな記述があります。

モジュール | Vuex

modules: {
 foo: {
   namespaced: true,

   getters: {
     // `getters` はこのモジュールのゲッターにローカライズされています
     // ゲッターの第4引数経由で rootGetters を使うことができます
     someGetter (state, getters, rootState, rootGetters) {
       getters.someOtherGetter // -> 'foo/someOtherGetter'
       rootGetters.someOtherGetter // -> 'someOtherGetter'
     },
     someOtherGetter: state => { ... }
   },

   actions: {
     // ディスパッチとコミットもこのモジュール用にローカライズされています
     // ルートディスパッチ/コミットの `root` オプションを受け入れます
     someAction ({ dispatch, commit, getters, rootGetters }) {
       getters.someGetter // -> 'foo/someGetter'
       rootGetters.someGetter // -> 'someGetter'

       dispatch('someOtherAction') // -> 'foo/someOtherAction'
       dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'

       commit('someMutation') // -> 'foo/someMutation'
       commit('someMutation', null, { root: true }) // -> 'someMutation'
     },
     someOtherAction (ctx, payload) { ... }
   }
 }
}


で、記事「Vuexのモジュールから他のモジュールのメソッドを呼ぶには « LANCARD.LAB|ランカードコムのスタッフブログ」によるとこれを応用すれば他のモジュールから呼び出すことが出来るとか。

そう、「ルートからのアクセス」が可能なのです。他のモジュール(例えばbar)から前記のfoo内のsomeActionを呼ぶ場合、次のように書けばよかったのです。


modules: {
 bar: {
   namespaced: true,

   actions: {
     someAction ({ dispatch, commit, getters, rootGetters }) {
       dispatch('foo/someOtherAction', null, { root: true }) // -> 'foo/someOtherAction'
     },
   }
 }
}


なるほど!それで呼び出せるのか!



呼び出せない

自分の設定が間違っているのかとか、呼び出せているけどそのアクションの中身が動いてないのかとか、state管理が間違ってるのかとか、ログ取りながら検証してみたけどどうしても動いてない。諦め掛けていたけどふと思いついて書き換えたら、、動きました。

modules: {
 bar: {
   namespaced: true,

   actions: {
     someAction ({ dispatch, commit, getters, rootGetters }) {
       dispatch('modules/foo/someOtherAction', null, { root: true }) // -> 'foo/someOtherAction'
     },
   }
 }
}


マジか。そんなことか。そういえばmiddlewareとかから呼び出すときだってそうしてたわ。

export default function({ store, error, app }) {
 store.dispatch('modules/foo/someOtherAction', { app: app })
 store.commit('modules/foo/someOtherMutation, state)
}


というわけで無事解決しました。やれやれ。



参考サイト:

Vuexのモジュールから他のモジュールのメソッドを呼ぶには « LANCARD.LAB|ランカードコムのスタッフブログ
Nuxt.js: storeモジュールから別のstoreモジュールのstateを参照する方法 – Qiita