Vue CLI3 で作成した SPA(Single Page Application)プロジェクト上で、段階的に Vue.js を学んで行きましょう。
今回は Vuex モジュール編です。
前提事項
API コール編 が完了していること。
Vuex モジュール
アプリケーションの全ての状態は、一つの大きなストアオブジェクトに内包されます。しかしながら、アプリケーションが大きくなるにつれて、ストアオブジェクトは膨れ上がってきます。そのため Vuex ではストアをモジュールに分割できるようになっています。
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> `moduleA` のステート
store.state.b // -> `moduleB` のステート
counter モジュール
Vuex 編で作成したカウンターを Vuex のモジュールを使うよう修正します。
src/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const counter = {
namespaced: true, // モジュールの名前空間を有効にする
state: {
count: 0,
},
getters: {
double(state) {
return state.count * 2
},
},
mutations: {
increment(state) {
state.count++
},
decrement(state) {
state.count--
},
},
actions: {
increment(context) {
context.commit('increment')
},
// 引数に ES2015 の引数分割束縛を使った例(context を省略できる)
decrement({ commit }) {
commit('decrement')
},
},
}
export default new Vuex.Store({
modules: {
counter: counter
},
})
Counter.vue も修正します。
src/views/Counter.vue
export default {
// ...
computed: {
// counter モジュールの state を参照する
...mapState({
count: state => state.counter.count
}),
// counter モジュールの getter を名前空間を使用して参照する
...mapGetters({
double: "counter/double"
})
},
methods: {
// counter モジュールの action を名前空間を使用して参照する
...mapActions({
increment: "counter/increment",
decrement: "counter/decrement"
})
}
};
todoList モジュール
コンポーネント編で作成した TODO List を Vuex のモジュール機能を使うよう修正します。
src/store.js
// ...
const counter = {
// ...
}
const todoList = {
namespaced: true, // モジュールの名前空間を有効にする
state: {
todos: [],
},
getters: {
todos(state) {
return state.todos
}
},
mutations: {
todos(state, todos) {
state.todos = todos
},
remove(state, idToRemove) {
state.todos = state.todos.filter(todo => {
return todo.id !== idToRemove
})
}
},
actions: {
getTodos({ commit }) {
fetch('http://localhost:8080/todos.json')
.then(response => response.json())
.then(json => {
console.log(json)
commit('todos', json.todos)
})
.catch(error => console.error('Error:', error))
}
}
}
export default new Vuex.Store({
modules: {
counter: counter,
todoList: todoList,
},
})
TodoList.vue も修正します。
src/views/TodoList.vue
import TodoListItem from "../components/TodoListItem";
import TodoInputText from "../components/TodoInputText";
import { mapGetters } from "vuex";
import { mapMutations } from "vuex";
import { mapActions } from "vuex";
export default {
components: {
TodoListItem,
TodoInputText
},
created() {
this.getTodos();
},
computed: {
...mapGetters({
todos: "todoList/todos"
})
},
methods: {
...mapMutations({
remove: "todoList/remove"
}),
...mapActions({
getTodos: "todoList/getTodos",
add: "todoList/add"
}),
removeTodo(idToRemove) {
this.remove(idToRemove);
},
addTodo(text) {
this.add(text);
}
}
};
コンポーネント編の演習で TODO を追加できるようにした方は、それらの機能も Vuex のモジュールを使うよう修正してみてください。
動作確認
カウンター、TODO リストともに以前と同様に動くか確認してください。