【vue.js】namespacedを使ってvuexをモジュール化する

はじめに

namespacedを使ってvuexをモジュール化する方法について

前提

現在、vuexストアの構成はapp/javascript/store/index.jsファイルがあるだけで、そこにタスク関連の状態管理を記述しています。

今後ユーザーなどの状態管理もするために、設定ファイルをモジュール化して管理しようと思います。

具体的には、新たにapp/javascript/store/modules/tasks.jsファイルとapp/javascript/store/modules/users.jsファイルを作成し、

そのファイルにそれぞれの状態管理を記述し、app/javascript/store/index.jsにインポートするようにします。

store/modules/tasks.jsファイルを作成

下記コマンドでapp/javascript/store/modules/tasks.jsファイルを作成します。

$ touch app/javascript/store/modules/tasks.js

app/javascript/store/index.jsファイルに記述していたタスク関連の状態管理のコードを、app/javascript/store/modules/tasks.jsファイルに移動して、エクスポートします。

その際namespacedを使って管理しやすくします。

import axios from '../../plugins/axios'

const state = {
  tasks: []
}

const getters =  {
  tasks: state => state.tasks
}

const mutations = {
  setTasks: (state, tasks) => {
    state.tasks = tasks
  },
  addTask: (state, task) => {
    state.tasks.push(task)
  },
  deleteTask: (state, deleteTask) => {
    state.tasks = state.tasks.filter(task => {
      return task.id != deleteTask.id
    })
  },
  updateTask: (state, updateTask) => {
    const index = state.tasks.findIndex(task => {
      return task.id == updateTask.id
    })
    state.tasks.splice(index, 1, updateTask)
  },
}

const actions = {
  fetchTasks({ commit }) {
    axios.get('tasks')
      .then(res => {
        commit('setTasks', res.data)
      })
      .catch(err => console.log(err.response));
  },
  createTask({ commit }, task) {
    return axios.post('tasks', task)
      .then(res => {
        commit('addTask', res.data)
      })
  },
  deleteTask({commit}, task) {
    return axios.delete(`tasks/${task.id}`)
      .then(res => {
        commit('deleteTask', res.data)
      })
  },
  updateTask({commit}, task) {
    return axios.patch(`tasks/${task.id}`, task)
      .then(res => {
        commit('updateTask', res.data)
      })
  }
}

export default {
  namespaced: true,
  state,
  getters,
  mutations,
  actions
}

store/modules/users.jsファイルを作成

app/javascript/store/modules/users.jsファイルを作成します。

$ touch app/javascript/store/modules/users.js

ユーザー関連の状態管理の記述は今後作成します。

const state = {
}

const getters =  {
}

const mutations = {
}

const actions = {
}

export default {
  namespaced: true,
  state,
  getters,
  mutations,
  actions
}

store/index.jsファイルを修正

最後にapp/javascript/store/index.jsファイルに、先程作成したファイルをインポートします。

import Vue from 'vue'
import Vuex from 'vuex'
import tasks from './modules/tasks'
import users from './modules/tasks'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    tasks,
    users
  }
})

上記のように、インポートしたストアをmodulesというキーに対して割り当てることで、vuexのモジュール化ができます。

vuexのデータをvue側で呼び出す

<template>
........
........
</template>

<script>
import { mapGetters, mapActions } from 'vuex'
........
........
export default {
.......
.......
  computed: {
    ...mapGetters('tasks', [ 'tasks' ]),
    // ...mapGetters([ 'tasks' ]) ← namespaced していない時
.......
.......
  created() {
    this.fetchTasks();
  },
......
......
  methods: {
    ...mapActions('tasks', [ 'fetchTasks', 'createTask', 'updateTask', 'deleteTask' ]),
  //  ...mapActions([ 'fetchTasks', 'createTask', 'updateTask', 'deleteTask' ])  ← namespaced していない時

タスクの状態管理のストアは、namespacedを使ってネストしているため、その中のgetteractionsを呼び出す時も、

明示的にネストしていることを記述する必要があります。