【今更シリーズ】Vuexのmapヘルパーを今更まとめてみた

# はじめに

こんにちは、フロントエンドエンジニアをちょっとしているものです。
最近転職をし、今までプライベートでしか使ってなかった Vuex をふんだんに使っていたので改めて勉強しました。

その中で Vuex の map ヘルパーを初めて使ったので、自分でまとめたものをアウトプットしようと思います。

# ヘルパーの種類

まず Vuex の map ヘルパーたちの紹介をします。

1. mapState
2. mapGetters
3. mapMutations
4. mapActions

の 4 つが現状存在します。
今回本業で利用していたのが、

`mapGetters`,`mapActions`

だったので 2 つの紹介をさせていただきます。

多分、他の`mapState`,`mapMutations`も利用方法は似ていると思うので、そちらは各々で調べてください。笑

## 前提条件

今回は、Nuxt.js で`sample-app`というよくある数字カウントアプリを作成して説明させていただきます。

各mapヘルパーの使い方は大きく分けて2つ紹介します。
- mapGetters
  - index.js[ts]内で使われているgettersを呼び出す書き方
  - store/**/**.js[ts]内で使われているgettersを呼び出す書き方
- mapActions
  - index.js[ts]内で使われているgettersを呼び出す書き方
  - store/**/**.js[ts]内で使われているgettersを呼び出す書き方

上記のように、index.jsとモジュール化したstore内のディレクトリから呼び出す方法があります。
書き方が若干異なるので（パスを指定するだけですが・・・）使いたい方で実装してみてください！

まずは
`pages/index.vue`
`store/index.js`
`store/sample/third.js`
のファイルを紹介させていただき、その内容を見ながら説明します。

#### pages/index.vue

```javascript:pages/index.vue
<template>
  <div class="template">
    <div>number:{{ number }}</div>
    <button @click="numberSum">number +1</button>

    <div>numberSecond:{{ numberSecond }}</div>
    <button @click="numberMultiplication">numberSecond *2</button>

    <div>numberThird:{{ numberThird }}</div>
    <button @click="numberMultiplicationThird">numberThird *3</button>
  </div>
</template>

<script>
import Vue from "vue";
import { mapGetters, mapActions } from "vuex";

export default Vue.extend({
  name: "IndexPage",
  computed: {
    ...mapGetters(["number", "numberSecond"]), // ①
    ...mapGetters("sample/third", ["numberThird"]), // ②
  },
  methods: {
    ...mapActions(["setNumber", "setNumberSecond"]), // ③
    ...mapActions("sample/third", ["setNumberThird"]), // ④

    numberSum() {
      this.setNumber();
    },
    numberMultiplication() {
      this.setNumberSecond();
    },

    numberMultiplicationThird() {
      this.setNumberThird();
    },
  },
});
</script>

<style scoped>
.template {
  margin: 100px auto 0;
  text-align: center;
  font-size: 4rem;
}
</style>
```

#### store/index.js

```javascript:store/index.js
export const state = () => ({
  number: 1,
  numberSecond: 1,
})

export const getters = {
  number: (state) => state.number,
  numberSecond: (state) => state.numberSecond
}

export const mutations = {
  SET_NUMBER(state) {
    state.number = state.number + 1
  },
  SET_NUMBER_SECOND(state) {
    state.numberSecond = state.numberSecond * 2;
  }
}

export const actions = {
    setNumber({commit}) {
        commit('SET_NUMBER')
    },
    setNumberSecond({commit}) {
        commit('SET_NUMBER_SECOND')
    }
}

```

#### store/sample/third.js

```javascript:store/sample/third.js
export const state = () => ({
  numberThird: 1,
});

export const getters = {
  numberThird: (state) => state.numberThird,
};

export const mutations = {
  SET_NUMBER_THIRD(state) {
    state.numberThird = state.numberThird * 3;
  },
};

export const actions = {
  setNumberThird({ commit }) {
    commit("SET_NUMBER_THIRD");
  },
};
```

#### ディレクトリ構成

ディレクトリ構成はこのような感じです。
ほかフォルダは省略しています。

```
.
├── pages
│   └── index.vue
~~~~~~~~~~~~~~~~~
└── store
    ├── index.js
    └── sample
        └── third.js

```


# mapGetters
このmapヘルパーですが、公式にはこのように記載されています。（[`mapStateヘルパー`の説明](https://vuex.vuejs.org/ja/guide/state.html#mapstate-%E3%83%98%E3%83%AB%E3%83%91%E3%83%BC)）

>コンポーネントが複数のストアのステートプロパティやゲッターを必要としているとき、これらすべてにおいて、算出プロパティを宣言することは繰り返しで冗長です。これに対処するため、算出ゲッター関数を生成し、いくつかのキーストロークを省くのに役立つ mapState ヘルパーを使うことができます:

公式に記載があるように、いちいちstoreのプロパティとか呼び出すのめんどいから、一括で呼べる方法あるよーっていう感じです。

### 使い方
それでは`mapGetters`の利用方法を見ていきましょう。
`pages/index.vue`に予め、`Vuex`よりimportしているのが前提で話をすすめます。

> ...mapGetters(["number", "numberSecond"]), // ①

上記、①のように`mapGetters`を使うと、`store/index.js`内のgettersを指定することによって、`computed`内で利用することができます。
注意点としては、必ずスプレット構文（...←これのこと）で記述する必要があります。
理由としては、mapヘルパーではオブジェクトを返すため、オブジェクト内にオブジェクトのような形でネストしてしまうためです。
詳細は[こちら](https://qiita.com/Statham/items/046649bff81c00ba275e)で分かりやすく説明されているので気になった方はクリックしてみてください。

あとは、`computed`として利用するだけです。

また、`store/**/**.js[ts]`の`getters`を利用したい場合は、
`...mapGetters("sample/third", ["numberThird"])`のように記述します。
第一引数に、store以下のパスを記述し参照するファイルを指定します。
そして第二引数に、利用する`getters`を配列で呼び出すことで利用することが可能です。

> ...mapGetters("sample/third", ["numberThird"]), // ②

# mapActions
こちらのヘルパーも`mapGetters`と使い方は一緒です。

### 使い方
それでは`mapActions`の利用方法を見ていきましょう。

> ...mapActions(["setNumber", "setNumberSecond"]), // ③

`mapGetters`と大きく違う点は、`methods`内で利用することぐらいでしょうか。

> ...mapActions("sample/third", ["setNumberThird"]), // ④

また、`store/**/**.js[ts]`の`actions`を利用したいときも同様で、
第一引数に、store以下のパス
第二引数に、利用する`actions`を指定することで利用できます。


# 最後に

mapヘルパー使いやすくないですか？
ぜひ冗長回避に使ってみてください！！