とあるWeb屋の備忘録

とあるWeb屋の備忘録。たまに雑記。

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です。
よりシンプルに書くために、分割代入を使って使いたいコンストラクタオプションを呼び出して使います。(上の例ではcommitstateを分割代入して使っています)
また、アクションハンドラは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