Nuxt.jsのdataはvuexのstate,gettersで管理しよう

##はじめに

vueinstanceでは親子component同士でdataを通信をする場合は`Props/$emitco`やcomponent同士でデータ通信をするためには`Event Bus`を使うのが一般ですがこのように複雑なdata通信を簡単に通信することができる考え方がVuxです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611034/8a48f778-07fb-e94d-f29d-bfe300a21551.png)

##Vuexとは
ざっくりですが下記のイメージ図のように中央管理所からデータを必要な時呼び出しして使えるイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611034/dae80d04-2bbc-4e12-2fcf-e03fd3cfc340.png)

自分のイメージだと親と子component同士関係なく中央管理所からdataを管理し必要な時使うのがVuexでつまり中央管理所はVuexとのことです。

公式からの説明は下記です。
>Vuex は Vue.js アプリケーションのための 状態管理パターン + ライブラリです。 これは予測可能な方法によってのみ状態の変異を行うというルールを保証し、アプリケーション内の全てのコンポーネントのための集中型のストアとして機能します。 また Vue 公式の開発ツール拡張と連携し、設定なしでタイムトラベルデバッグやステートのスナップショットのエクスポートやインポートのような高度な機能を提供します。
https://vuex.vuejs.org/ja/


##vuex使い方
nuxtインストールは公式サイト参考　https://ja.nuxtjs.org/guide/installation
nuxtをインストールしたら`vuex`をインストールします。

```
$ npm i vuex
```
nuxtのプロジェクトを作成すると直下に`store`フォルダが作成されるので`store`直下にindex.jsを新しく作って下記のサンプルコードのようにvuexをimportして必要なdataの登録をします。

```store/index.js
import Vuex from 'vuex'

export const appStore = () => {
  return new Vuex.Store({
    state: {//data
      myData:{
        firstName: 'thunder',
        lastName: 'fury',
      }
    },
    mutations: {
    },
    actions: {
    }
  })
};
export default appStore
```
vuexの`state`はvueinstanceで言うと下記のdataの役割です。
storeにあるdataを使うためには`$store`で呼び出しができます。

```.js
<template lang="pug">
  div
    p {{ $store.state.myData.firstName }}
    p {{ $store.state.myData.lastName }}
</template>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611034/50b4ad1a-f16b-f8ff-48bc-02d92b883772.png)
これでも良いですがdataのオブジェクトの下層が深い場合など繰り返しコードが多くなってしまうのでその時使うのが`Getters`です。
##Getters実行イメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611034/9c49a662-28c0-6eb4-6a77-85a19a531fa1.png)

storeのindex.jsにstateのdataをgettersに関数として登録してreturnして使える流れです。

```store/index.js.js
getters: {
   myData: state => {
      return state.myData
   },
//上下同じ
getters: {
   myData: function(state) {
      return state.myData
   },
```
どちらでも書き方は問題ないです。
少しでもにコード量を減らすためにはarrow functionが良いか思います。

登録が終わったら使いたいvueのcomponent`mapGetters`をimportをして`computed`に`store/index.js`宣言した関数を配列の中に入れます。
そうすることに寄って`$store.state`から呼び出したのをcomponent内でで宣言したようにで呼び出しすることができます。
[](componentからDispatch使ってActions実行しActions内でMutationsをCommitしたらStateに変更する形でvuexが動作される流れです。)

```.js
<template lang="pug">
  div
    p {{ myData.firstName }}　//　p {{ $store.state.myData.firstName }}が省略できる
    p {{ myData.lastName }} //　p {{ $store.state.myData.firstName }}が省略できる
</template>
<script>
import { mapGetters } from 'vuex'　//ここにmapGettersをimport
export default {
  computed: {
    ...mapGetters(['myData']) //ここでmapGettersを使う
  }
}
</script>

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611034/50b4ad1a-f16b-f8ff-48bc-02d92b883772.png)
結果`$store.state.myData.firstName`を呼び出した時と同じくなります。
`getters`で宣言した関数名を別の名前で受け取りする方法も有って配列で受けたのをオブジェクトで受け取ってのkeyとvalueで割当して使うこともできます。:sunny:

```.js
computed: {
    ...mapGetters({
       testData:'myData'
    })
  }
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611034/50b4ad1a-f16b-f8ff-48bc-02d92b883772.png)

同じ結果です。:sunny:
このように別のvueComponentを作ってもわざわざ処理をしなくてもimportだけでdataを呼び出しして使うことができます。グロバル関数系の`mutations`や`actions `もありますが自分は`Mixin`でグロバル化して使っても十分使えるかと思いました。

##終わり
ページを遷移した場合データの渡すしや受けるなどサイトが膨大になると複雑になるので中大サイトをもし、vueで作成する場合vuexのgettersを使って簡単に管理するのがどうですか