Help us understand the problem. What is going on with this article?

Vuexでasync/awaitを用いて値を返すアクションを記述する

More than 1 year has passed since last update.

何を今更ということかもしれないけれど、自分にとってかなりの:sunrise:新しい地平が開けた感:sunrise:があったので一応記事として残しておくことにしました。

そもそもVuexのアクションとは?

https://vuex.vuejs.org/ja/guide/actions.html

アクションは、状態を変更するのではなく、ミューテーションをコミットします。
アクションは任意の非同期処理を含むことができます。

自分もアクションはミューテーションをコミットしたりするものだと思ってました(その通りです)。
ユーザが何か操作すると、それをトリガーにアクション、ミューテーション、ステートと処理が伝播していき、ステートの変化がUIに反映されたりして、ユーザに伝わるというのが通常のVuexの流れだと思います。
そのようにVuexを書いていたあるとき、Vuexの複数のアクションの処理が抽象化出来そうな状況が生まれました:eyes:
そこでふと立ち止まってしまいました。アクションの返り値は何なのだと:thinking:

抽象化出来そうなアクション

そこで、CodeSandboxで以下のようなVuexコードを試してみました:pencil:

https://codesandbox.io/s/vue

import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";

Vue.config.productionTip = false;

Vue.use(Vuex);

const store = {
  state: {
    text: "hello"
  },
  actions: {
    doubleText({ state }) {
      let newText = [];
      for (let i = 0; i < 2; i++) {
        newText.push(state.text);
      }
      newText = newText.join("!! ") + "!!";
      console.log(newText);
    },
    tripleText({ state }) {
      let newText = [];
      for (let i = 0; i < 3; i++) {
        newText.push(state.text);
      }
      newText = newText.join("!! ") + "!!";
      console.log(newText);
    }
  }
};

new Vue({
  render: h => h(App),
  store: new Vuex.Store(store),
  mounted() {
    this.$store.dispatch("doubleText");
    this.$store.dispatch("tripleText");
  }
}).$mount("#app");

2つのアクション内で、文字列をループで回して増やしている部分を共通化出来そうです。

import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";

Vue.config.productionTip = false;

Vue.use(Vuex);

const store = {
  state: {
    text: "hello"
  },
  actions: {
    multiText({ state }, num) {
      let newText = [];
      for (let i = 0; i < num; i++) {
        newText.push(state.text);
      }
      return newText.join("!! ") + "!!";
    },
    doubleText({ dispatch }) {
      const text = dispatch('multiText', 2);
      console.log(text);
    },
    tripleText({ dispatch }) {
      const text = dispatch('multiText', 3);
      console.log(text);
    }
  }
};

new Vue({
  render: h => h(App),
  store: new Vuex.Store(store),
  mounted() {
    this.$store.dispatch("doubleText");
    this.$store.dispatch("tripleText");
  }
}).$mount("#app");

単純にまとめてコンソールを確認すると、Promiseが返ってきました。
な、なるほどーー :flushed:

async/awaitを用いたアクション

ということは、async/awaitが使えるということで、
実はこれは公式ドキュメントにも書かれています:thumbsup:

https://vuex.vuejs.org/ja/guide/actions.html#%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E6%A7%8B%E6%88%90%E3%81%99%E3%82%8B

import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";

Vue.config.productionTip = false;

Vue.use(Vuex);

const store = {
  state: {
    text: "hello"
  },
  actions: {
    multiText({ state }, num) {
      let newText = [];
      for (let i = 0; i < num; i++) {
        newText.push(state.text);
      }
      return newText.join("!! ") + "!!";
    },
    async doubleText({ dispatch }) {
      const text = await dispatch('multiText', 2);
      console.log(text);
    },
    async tripleText({ dispatch }) {
      const text = await dispatch('multiText', 3);
      console.log(text);
    }
  }
};

new Vue({
  render: h => h(App),
  store: new Vuex.Store(store),
  mounted() {
    this.$store.dispatch("doubleText");
    this.$store.dispatch("tripleText");
  }
}).$mount("#app");

そこに書いていいのかという疑問はありつつも、これでアクションに普通の関数(のようなもの)が書けました:thumbsup:
ひとつ賢くなりました:raised_hands::two_hearts::beers::sushi::kissing_heart:

kiyc
Webエンジニア。インフラもバックエンドもフロントエンドも書いています。 普段書いているのはPHP(Laravel)、JavaScript(Vue.js)です。
prime-order
組織と業務に変革をもたらす新しいカタチのシステム開発サービス
https://prime-order.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした