【Vue.js】【Vuex】Storeを分割してモジュール化し、namespacedを登録する
実装したいこと
Vuexのストアをモジュールに分割して読み込みたい。
アプリケーションの規模が大きくなると、ストアの規模も大きくなり管理が困難になるため、ストアを適切に分割し管理したい。
モジュールを読み込む
store/index.js
にまとめていたstore
をstore/modues/task.js
に切り出す。
import Vue from 'vue' import Vuex from 'vuex' import tasks from './modules/task' // 分割したモジュールを呼び出す Vue.use(Vuex) export default new Vuex.Store({ modules: { tasks // 追加 } })
import axios from '../../plugins/axios' // taskモジュールを定義 export default { // 注意(後述) namespaced: true, // 名前空間 'namespaced'なことに注意 state: { tasks: [], }, getters: { tasks: (state) => state.tasks }, actions: { fetchTasks({ commit }) { axios.get("tasks") .then(response => { commit('loadTasks', response.data) }) .catch(error => console.log(error.status)); } } }
エラー
2時間位溶かす。エラーの切り出しが下手で時間がかかってしまいます…
今見たら、エラー文にちゃんと原因が書いてあった。すぐgoogleで調べる癖は悪なので反省
①名前空間をつけたモジュールが読み込めない…
vuex.esm.js:345 Uncaught TypeError: Cannot read property 'getters' of undefined ERROR in ./app/javascript/store/index.js 8:10-14 "export 'default' (imported as 'task') was not found in '../store/modules/task'
// taskモジュールを名前付きで定義 export const task = { namespaced: true,
名前付きのexportnamed export
でなく、export default
にしたら直った
②namespaced: true
タイポ
namespace: true
にしてた…
呼び出し側
<script> import { createNamespacedHelpers } from 'vuex' // 追加 const { mapActions, mapGetters } = createNamespacedHelpers('tasks') // 追加 export default { computed: { ...mapGetters(["tasks"]) }, created() { this.fetchTasks(); }, methods: { ...mapActions([ "fetchTasks" ]) } } </script>
createNamespacedHelpers
というヘルパーを使ったら簡単にできました。
これを使わない場合は、第一引数にモジュール名を渡せばOK
...mapGetters( "tasks",["tasks"]) ...mapActions("tasks",[ "fetchTasks" ])