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

Vuex のマップ系ヘルパーの書き方決定版!

More than 1 year has passed since last update.

はじめに

VuexのmapStatemapActionsって便利ですけど、色々な書き方があってややこしいですね。

例えば、以下のケースでそれぞれ書き方が変わってきます。

  • ヘルパー以外のプロパティも定義したい場合
  • モジュールから値を取ってきたい場合
  • 値にエイリアス(別名)をつけたい場合
  • 値に何らかの処理をほどこしたい場合

本記事では「この2パターンだけ覚えていればOK」という書き方をご紹介します。

前提

前提として、userというモジュールに、idageというステートが定義されているとします。

store/index.js
const user = {
  state: {
    id: ''
    age: null
  },
  namespaced: true,
}

また、必要なヘルパーはインポートされているとします。

pages/index.vue
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'

書き方1(簡易型)

まずは、よく使う簡易的な書き方から。

ストアの値をそのまま使うだけの場合は、以下のように書けます。

pages/index.vue
  computed: {
    ...mapState('user', [
      'id', 
      'age'
    ]),

    // この後にもちゃんと関数を定義できる

  },

これにより、userモジュールのid, agethis.id, this.age で取得できます。

参照先がモジュールじゃない場合は第1引数を省略するだけです。

モジュールじゃない場合
  ...mapState([
    'some', 
    'states'
  ]),

他の3つのヘルパーも同様に書けるので省略します。
(ただしmapMutationsmapActionsは、computedではなくmethods内に定義します)

書き方2(万能型)

こちらはあらゆるケースで使える書き方です。
(ただエイリアスや値の加工が不要な場合は、書き方1より冗長になります)

  computed: {
    ...mapState('user', {
      userId: 'id',
      isAdult: function(state) {
        return state.age > 19, // 成人かどうかを Boolean で返す
      },
    }),

    // この後にもちゃんと関数を定義できる
  },

書き方1と異なるのは、引数に配列ではなくオブジェクトを渡している点です。
そのオブジェクトには、

エイリアス名: '取得したいキー名' あるいは
エイリアス名: function (MapGetters 以外)

という形のプロパティを定義します。
(function を渡すやり方については下で補足解説します)

:point_up:のコードでは、

  • this.userIdで user のidが取得できる
  • this.isAdultで「年齢が20歳以上かどうか」が取得できる

ようになっています。

補足(function を渡す書き方)

mapState, mapMutations, mapActionsでは、プロパティに function を渡すことで値の加工や処理の追加が行えます。

  • mapStateの場合はstateを引数とし、加工した値を戻り値とします。

  • mapMutations, mapActionsの場合はそれぞれcommit, dispatchを引数とし、行いたい処理を記述します。実例を置いておきます。

※「値を加工するなら getters に書けばいいのでは?」と思われるかもしれませんが、例えば一つのページでしか使わないような値の場合、こうすることで getters の肥大化が避けられます。

その他の注意点

  • ヘルパーを書く場所は、

    • mapState, mapGetterscomputed
    • mapMutations, mapActionsmethods
  • 参照先がモジュールではない場合は第1引数を省略する

  • モジュールがネストしている場合は、モジュール名をスラッシュで区切って指定する。例:”user/photo”

参考

Vuex:mapStateの書き方8パターン+11サンプルコード

POPOPON
Vue好き
commew
ゆるく、つながる、たすけあう 困りごとの共有や相談、学習報告などを通して「ひとりで働いていても孤独ではない」空間へ
https://commew.net/
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