Nuxt.jsで認証認可入り掲示板APIのフロントエンド部分を構築する #2 NuxtとRailsとの疎通テスト

←[Nuxt.jsで認証認可入り掲示板APIのフロントエンド部分を構築する #1 環境構築](https://qiita.com/rf_p/items/0277ae96c5de433b4849)

# axiosの導入

URLのリクエストを送る際はaxiosを使います。
create_nuxt_appの時にaxiosを入れているはずですが、もし入れるのをミスっていた場合は以下の手順で追加します。

```powershell
$ yarn add @nuxtjs/axios
```

```diff:nuxt.config.js
export default {
   ** Nuxt.js modules
   */
   modules: [
+    '@nuxtjs/axios'
   ],
```

# APIとの疎通テスト

```diff:pages/index.vue
           Welcome to the Vuetify + Nuxt.js template
         </v-card-title>
         <v-card-text>
+        <ul>
+          <li v-for="post in posts" :key="post.id">
+            {{ post.subject }}
+            {{ post.body }}
+          </li>
+        </ul>
...
   components: {
     Logo,
     VuetifyLogo
+  },
+  async asyncData({ $axios }) {
+    const response = await $axios.$get('/v1/posts');
+    return {
+      posts: response.posts
+    };
   }
 }
 </script>
```

雑ではありますが、Railsのseedで作ったデータが無事に取得できましたね。

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/1c1dc499-a59b-6814-a037-ec30c785b881.png)

とりあえずこれでフロントエンドとバックエンドの連携確認は取れました。

# Vuexで書き換える

特にルール無く記述していくことも可能なのですが、Vuexを利用して書いていきます。

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

![vuex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/56a7e88e-8ef2-7a41-fa8a-e236c34201f8.png)

文章・画像引用：[Vuex とは何か？ | Vuex](https://vuex.vuejs.org/ja/)

文章を読んだり画像をパッと見ただけではなかなか理解しづらいかもしれません。
actionsやらmutationsやらdispatch, commit…なにこれ？と思うかもしれませんが、

* storeに`state`、`mutations`、`actions`の3つ(+`getters`の4つ)を持ってそれぞれを呼び出すというパターン
* `state`は値を持つだけ
* `mutations`はstateの値をセットするだけ
* `actions`で処理して、stateを変更する時は直接stateを呼ばずmutationsを呼ぶ
* `getters`はstateの値を取得するだけ
* `mutations`を呼ぶことを`commit`と言う
* `actions`を呼ぶことを`dispatch`と言う

となります。

とりあえず以下のようにファイルを編集します。

```javascript:store/posts.js
export const state = () => ({
  posts: []
})

export const getters = {
  posts (state) {
    return state.posts
  }
}

export const mutations = {
  setPosts (state, data) {
    state.posts = data
  }
}

export const actions = {
  async fetchPosts () {
    return await this.$axios.$get('/v1/posts')
  }
}

```

```vue:pages/index.vue
<template>
  <v-layout
    column
    justify-center
    align-center
  >
    <v-flex
      xs12
      sm8
      md6
    >
      <v-card v-for="post in posts" :key="post.id">
        <v-card-title class="headline">
          {{ post.subject }} - {{ post.user.name }}
        </v-card-title>
        <v-card-text>
          {{ post.body }}
        </v-card-text>
      </v-card>
    </v-flex>
  </v-layout>
</template>

<script>
export default {
  async fetch ({ store }) {
    const posts = await store.dispatch('posts/fetchPosts')
    store.commit('posts/setPosts', posts.posts)
  },
  computed: {
    posts () {
      return this.$store.getters['posts/posts']
    }
  }
}
</script>
```

storeディレクトリ以下に置いたファイルは、{ファイル名}/{関数名}で名前空間が切られます。
どのように処理されているかの流れは、上記2ファイルに1〜8でコメント記載しています。

まずは`const posts = await store.dispatch('posts/fetchList') // 1`によって`posts/fetchList`の`dispatch`。
前述の通りdispatchはactionsを呼び出すので、`posts.js`の`actions`にある`fetchList`が呼ばれるわけですね。

一度見方が分かれば、そこまで読み解くのは難しくないはずです。

Vuexはルールを破って書くことができてその場合エラーを投げたりしないのですが、結局そうなるとコードの保守性は下がります。ですので上記ルールに従って、storeの直接呼び出しや書き換えをせずに、actionsやmutationsで制御していきましょう。

# 続き

→[Nuxt.jsで認証認可入り掲示板APIのフロントエンド部分を構築する #3 個別記事ページの作成](https://qiita.com/rf_p/items/fc7f0490a62b1f98f487)
【[連載目次へ](https://qiita.com/rf_p/items/0277ae96c5de433b4849#%E7%9B%AE%E6%AC%A1)】