AxiosとVuexって実際どう使えば良いの？

#はじめに

今回は**Nuxt.jsでAxiosやVuexを使って、サーバー通信からデータを表示するまでの流れ**を紹介します。

Nuxt.jsでAxiosを使うには、**@nuxtjs/axios**を用いることで、
サーバー側からデータを取得したり、更新したりすることができます。

またそのデータを今度は**Vuex**を使ってフロント側で状態管理します。

そしてそのデータを**ヘルパー関数**を使ってVuexから引っ張ってきて、
実際に画面に表示していきます。

簡単にまとめると、
**①Axiosでサーバー側からデータ取得**
**②Vuexでデータの管理**
**③データを画面に表示**
という流れです！

実際に手もとで試したいという方は、まずNuxtのプロジェクトを作成しましょう。

```
// npmを使う場合
npx create-nuxt-app プロジェクト名

// yarnを使う場合
yarn create nuxt-app プロジェクト名
```

※プロジェクト作成時の細かい設定については、他の記事をご参照ください。
※また、今回解説する実装方法以外にも色々なパターンがあるかと思いますが、今回はあくまでも一例を紹介いたします。

では本題に入っていきます。

## @nuxtjs/axiosのインストール・設定

まずは@nuxtjs/axiosをインストールします。

```
npm install --save @nuxtjs/axios
```

package.jsonに@nuxtjs.axiosが入っていたら、ちゃんとインストールされていることになります。

```package.json
"dependencies": {
  "@nuxtjs/axios": "バージョン"
}
```

次にNuxt.js用のaxiosをの設定を行います。
nuxt.config.jsの、pluginsとmodulesに記述します。

```nuxt.config.js
plugins: [
  '@/plugins/axios.js'
],
modules: [
  '@nuxtjs/axios'
]
```

## Axiosを使ってデータを取得する

早速データ取得のコードを書いていきます。


今回、データ取得はVuexでいうActiosというところで行いますが、Vuexの詳細については後ほど解説します。
storeのJSファイルに記述します。

**{ store/index.js ]**

```index.js
export const actions = {
  async fetchData({ commit, state }) {
    try {
      const resp = await this.$axios.$get('ここにAPIのエンドポイントを入れます')
      commit('setData', resp)
    } catch (error) {
      console.log(error)
    }
  }
}
```

Actionsの中にfetchDataという関数を作り（名前は何でも良い）、
try/catch文の中でデータ取得を行っています。

`this.$axios.$get('APIのエンドポイント')`
でデータ取得が行えます。
また、データを更新したい時には**$get**の部分を**$post**にします。

resp（名前は何でも良い）変数に取ってきたデータを格納し、
**commit**を使ってMutationsのsetDataという関数の方に渡しています。
（※Mutationsについては後ほど）

## Vuexで状態管理

今度は、先ほどAxiosで取ってきたデータを、Vuexを使ってフロント側で管理していきます。

VuexにはState, Getters, Mutations, Actionsがありますが、
今回使うのは先程Axiosのところで出てきた**Actions**と、
これから出てくる**State**と**Mutations**です。
※Gettersは今回登場しません。

先程と同じstoreのJSファイルに追加で記述します。

**[ store/index.js ]**

```index.js
export const state = () => ({
  data: null
})

export const mutations = {
  setData: (state, value) => {
    state.Data = value
  }
}
```
処理の順番としては、
先程Actionsのところで取得してきたデータが、
**MutationsのsetData関数へ渡されています。**

そしてさらに、そのデータを**Stateのdataに渡しています。**

なので、Vuexの流れをもう一度まとめると、
**①ActiosでAxiosを使ってサーバからデータ取得**
**②Actios→Mutationsにデータをコミット**
**③Mutations→Stateにデータをセット**
という流れです！

## 実際にデータを画面に表示する

これまでで基盤は整いましたので、あとはデータを表示していきます。

と言いたいところですが、、
実はこれまでのコードだけでは実際にはデータが取得できていません！

先程Actionsで書いたAxiosのコードですが、
これは**Vueファイル側で呼び出さないと実行されません。**

なので、その呼びだす処理を書いていきましょう。
※呼び出す処理を書く場所についてはいろいろなパターンがありますので、今回はあくまでも一例です。

pagesディレクトリのVueファイルに記述していきます。

**[ pages/index.vue ]**

```index.vue
<script>
export default {
  fetch({ store }) {
    store.dispatch('index/fetchData')
  }
}
</script>
```

fetch内で**store.dispatch**を使うことで、
index.js内のfetchData関数を実行することができます。

また、今回は実際にデータを表示する部分を
conponentsディレクトリ配下のVueファイル（今回はTop.vueというファイルを作ります）に記述するので、
Top.vueをインポートするコードを追記します。
以下全体のコードです。

**[ pages/index.vue ]**

```index.vue
<template>
  <Top />
</template>

<script>
import Top from '@components/Top'

export default {
  components: {
    Top
  },
  fetch({ store }) {
    store.dispatch('index')
  }
}
</script>

```

では最後に、データを表示していきましょう！

cpmponentsディレクトリ配下のVueファイルに記述していきます。（今回はTop.vueを作成）

**[ comopnents/Top.vue ]**

```Top.vue
<template>
  <div>{{ data }}</div>
</template>

<script>
import { createNamespacedHelpers } from 'vuex'
const { mapState } = createNamespacedHelpers('index')

export default {
  computed: {
    ...mapstate(['data'])
  }
}
</script>
```

まずはscriptの一行目
`import { createNamespacedHelpers } from 'vuex'`
でvuexをインポートしてきています。
また今回は**createNamespacedHelpers**を使用するということも記述しています。

その下の
`const { mapState } = createNamespacedHelpers('index')`
では、index.jsのStateからデータを引っ張ってこれるように設定しています。

そしてcomputedの中で
`...mapstate(['data'])`
を使ってVuexのStateからdataプロパティを引っ張ってきています。

最後に、templateタグ内で**二重中括弧{{ }}**を使って、
dataを参照することで画面に表示することができます！

# 最後に

今回の流れをおさらいすると、

**①Axiosをインストールして設定する**
**②Axiosを使ってサーバーと通信し、データ取得処理の実装**
**③Vuex（State, Mutations, Actions）を使って状態管理を行う
　・データの流れは、Actions→Mutations→Stateの順**
**④store.dispatchを使って②の処理を実行**
**⑤mapStateを使ってVuexのStateからデータを持ってくる**
**⑥画面に表示**

という形で実装を行ってきました。

実装パターンはいくつかあると思いますが、
今回はあくまでも一例を紹介させていただきました。

ご参考になれば幸いです。

最後までお読みくださりありがとうございました。