Vuexのアクションについて
前回、Vuexのミューテーションについて説明しましたがミューテーションは以下のルールがあります。
ミューテーションハンドラ関数は同期的でなければならない
つまりミューテーションでできるのは同期処理のみで、非同期処理はできません。そのため実際に使うとなるとミューテーションだけでは辛くなります。
そのためにアクションがあり、アクションは非同期処理を行うことができます。
アクションはアクションハンドラをアクションに登録してそれを呼び出すことで使います。
実際にアクションハンドラを登録して、それを呼び出す方法を記載します。
やってることはただのカウントアップです。
// ストア側 state: { count: 0 } mutations: { [INCREMENT](state) { state.count += 1; } }, actions: { increment({ commit, state }) { // 例としてプロミスで非同期処理しています return new Promise((resolve, reject) => { setTimeout(() => { resolve("success"); }, 1000); if (state.count === null) { reject("err"); } }) .then(value => { console.log(value); commit("INCREMENT"); }) .catch(err => { console.log(err); return err; }); } }
// コンポーネント側 methods: { aaa() { this.$store.dispatch('increment') } }
やってることは以下です。(ミューテーションには定数を使っている前提です)
- ストア側に状態変更に使うミューテーション登録
- ストア側にそのミューテーションを使うためのアクション登録(登録したアクションハンドラの引数に
commit
渡してるのは後ほど説明します) - コンポーネント側のメソッドオプションにそのアクションを使うためのメソッドaaaを登録
aaaを使うとアクションハンドラ -> ミューテンションハンドラ -> ステート変更 の流れで処理されます。
ポイントになるところは、登録したアクションハンドラの引数にcommit
を渡しているところです。
アクションハンドラは引数にcontext
を取ります。context
とはストアインスタンスで持っているステート、ゲッター、ミューテーション、アクションなどと同じものを呼び出せるオブジェクトです。context
ごと渡してもOKです。
よりシンプルに書くために、分割代入を使って使いたいコンストラクタオプションを呼び出して使います。(上の例ではcommit
とstate
を分割代入して使っています)
また、アクションハンドラはdispatch
されることでトリガーされます。
ミューテーションハンドラはcommit
アクションハンドラはdispatch
アクションの使い方は以上になりますが、最後にコンポーネント側でアクションを呼び出すときの短縮記法を以下に記載しておきます。
// コンポーネント側 methods: { ...mapActions(["increment"]), // まずマップヘルパーに登録 aaa() { // this.$store.dispatch('increment') // これ冗長です this.increment() // これで上と同じ意味です } }
補足として説明してきたVueとVuex周りの用語で混乱しがちなものを以下にまとめました。
Vueのオプション
・data
・computed
・methods
Vuexのオプション
・state
・getters
・mutations
・actions
mutationsオプションに登録するもの
・mutationハンドラ
mutationsハンドラを呼び出すとき
・mutationの名前を指定してコミットする
actionsオプションに登録するもの
・actionハンドラ
actionsハンドラを呼び出すとき
・actionsの名前を指定してディスパッチする
次はモジュール分割について書きたいと思います。
ここまで読んでいただいてありがとうございました!!!
参考資料
アクション | Vuex