Vuexのストアをモジュールに分割する



Vuexストアのモジュール分割を試したのでまとめる。



moduleの作成方法


ストア作成と同時にモジュールを登録する方法

export const store = new Vuex.Store({
  //グローバルなstore
  state: {
    data: {
      message: 'グローバルなモジュールだよ'
    }
  },
  mudations: {
    
  },
  actions: {
    
  },
  getters: {
    
  },
  
  modules: {

    //moduleAを作成
    moduleA: {
      namespaced: true,
      
      state: {
        data: {
          message: 'モジュールAだよ'
        }
      },
      getters: {
      }
    }
  }
})


ストアが作られた後にモジュールを登録する方法

export const store = new Vuex.Store({
  // グローバルなストア
})

// store.registerModuleメソッドを使ってmoduleBモジュールを登録
store.registerModule('moduleB', {
  namespaced: true,
  
  state: {
    data: {
      message: 'モジュールBだよ'
    }
  },
  getters: {
 
  }
})



別ファイルをimportして登録する方法
moduleC.js

import { store } from '../store'
 
export default {
  namespaced: true,
  
  state: {
    data: {
      message: 'モジュールCだよ'
    }
  },
  getters: {
  }
}


store.js

export const store = new Vuex.Store({
  //グローバルなstore
  state: {
    data: {
      message: 'グローバルなモジュールだよ'
    }
  },
  mudations: {
    
  },
  actions: {
    
  },
  getters: {
    
  },

  modules: {
    //ここでmoduleCを読み込み
    moduleC: moduleC,
  }
})




namespaced: true とは


namespaced:オプションをtrueにすることで、それぞれのモジュールに名前空間を与えて呼び出し方を管理することができる。

ただstateについては、namespaced: trueの有無は関係なく一律で$store.state.(モジュール名).data.messageのように呼び出す。


その他のmutation, action, getterはnamespaced: trueを与えなかった場合はモジュールを使用せずグローバルに登録したときと同じように呼び出せる。


もしnamespaced: trueを与えていない複数のモジュール内で名前が被った場合、mutationとactionはそれぞれが同時に実行される。
getterは以下のようなエラーが発生する。

[vuex] duplicate getter key: greetingC



namespaced: trueを与えたmutation, action, getterは、名前の前にモジュール名/を付与して呼び出す。

console.log(this.$store.getters['moduleA/greeting']
console.log(this.$store.commit('moduleA/greeting')
console.log(this.$store.dispatch('moduleA/greeting')
// getterは[], mutationとactionは()で囲むので注意



名前空間が与えられていれば、モジュール内で同じモジュールのgetter, mutation, actionを呼び出すときにモジュール名を先頭に付ける必要は無い。

export default {
  namespaced: true,
  state: {
    data: {
      message: 'モジュールCだよ'
    }
  },
  mutations: {
    resetMessage(){
      // stateの呼び出しはいつでもモジュール名の宣言が必要
      store.state.moduleC.data.message = ''
    }
  },
  actions: {
    example(ctx){
       // 'moduleC/resetMessage'と書かなくてよい
      ctx.commit('resetMessage')
    }
  },
}



namespaced: true を与えたモジュールからグローバルに登録したストアオプションを呼び出す。


getterの第3, 第4引数にはrootState, rootGettersという値が渡されるようになる。
グローバルのstateやgetterを呼び出すにはこれらを使う。

  getters: {
    example: (state, getters, rootState, rootGetters) => {
      return rootState.data.name + 'さん ' + rootGetters.greeting 
    }
  }
// 太郎さん こんにちわ!



actionのコンテキストにもrootState, rootGettersが値として渡される。
また、commit, dispatchの第3引数にroot: trueというオプションを渡せばグローバルのmutation, actionを呼び出すことができる。

  actions: {
    getGreeting(ctx){
      
      let payload = ctx.rootGetters.greeting + " " + ctx.rootState.data.name
      
      ctx.commit('greeting', payload, { root: true })
    }
  }