ミューテーションはステートを更新するために用いられます。Vuexではミューテーション以外がステートの更新を行うことを禁止(やろうと思えば更新できますが、アンチパターン)しています。状態の更新を追いかけやすくするために、このような規約が設けられています。では、ミューテーションの定義方法と更新方法についてみていきましょう。
ミューテーションを定義してみよう
ミューテーションを定義するには、下記のようにストアの生成時にmutationsオプションを指定して、その中にハンドラ関数を定義します。今回はisLoggedInというハンドラ関数を定義しました。
1 2 3 4 5 6 7 8 9 10 | const store = new Vuex.Store({ state: { login: false }, mutations: { // ミューテーションを定義 isLoggedIn (state) { state.login = true } } }) |
ハンドラ関数は状態(state)を第1引数として取得し、状態の変更を行います。また、仮引数を追加することもできます。下記で仮引数を追加してみます。
1 2 3 4 5 6 7 | const store = new Vuex.Store({ mutations: { isLoggedIn (state, parameter) { // 仮引数parameterを追加 state.login = true } } }) |
状態(state)を更新してみよう
状態(state)の更新をしてみましょう。まず、覚えておく必要があるのは、ミューテーションは直接呼び出せないということです。つまり、store.mutations.inLoggedIn()のように使うことはできません。
では、どのように状態(state)を更新するのかというと、store.commitにミューテーション名や引数(ペイロードと呼びます)を与えて呼び出すことで実現します。
例えば、下記のようにハンドラ関数を呼び出します。
1 | store.commit('isLoggedIn') |
ペイロードを使用する場合は次のように書きます。
1 | store.commit('isLoggedIn', 100) // 第2引数で100という数値型を渡す |
ペイロードはオブジェクト型を使うことが推奨されています。そうすることで複数のフィールドを含められるようになり、またミューテーションがより記述的に記録されるようになるからです。
1 | store.commit('isLoggedIn', { myNumber: 100 }) |
console.logで確認すると次のように動作します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="https://unpkg.com/vuex@3.1.1/dist/vuex.js"></script> <script> const store = new Vuex.Store({ state: { login: false }, mutations: { isLoggedIn (state) { state.login = true } } }) const vm = new Vue({ el: '#app', store }) console.log(store.state.login) // false store.commit('isLoggedIn') // isLoggedInハンドラーを実行 console.log(store.state.login) // true </script> |
ペイロードを使った場合の動作も確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="https://unpkg.com/vuex@3.1.1/dist/vuex.js"></script> <script> const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state, num) { state.count += num } } }) const vm = new Vue({ el: '#app', store }) console.log(store.state.count) // 0 store.commit('increment', 10) // isLoggedInハンドラーを実行 console.log(store.state.count) // 10 </script> |