Nuxt.js + axiosで非同期データ通信ハンズオン風

# ここで言う非同期データ通信とは
- <font color="Salmon">apiサーバからデータを取得してページ上に表示する</font>こととします。

# 前提
- `npm v5.2.0以上`がローカルまたは開発環境に入っていること

# プロジェクト作成
```
create-nuxt-app [プロジェクト名]
```
- こんな感じで選択（Axiosを選択）
<img width="912" alt="スクリーンショット 2019-09-29 9.49.23.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303093/76ed02c3-7855-2777-3bee-bad9f5464ae6.jpeg">

- `package.json`に`axios`が入っていることを確認

```javascript:package.json

{
  "name": "async-test",
  "version": "1.0.0",
  "description": "My supreme Nuxt.js project",
  "author": "yosuke0517",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore ."
  },
  "dependencies": {
    "nuxt": "^2.0.0",
    "@nuxtjs/axios": "^5.3.6"
  },
  "devDependencies": {
    "@nuxtjs/eslint-config": "^1.0.1",
    "@nuxtjs/eslint-module": "^1.0.0",
    "babel-eslint": "^10.0.1",
    "eslint": "^6.1.0",
    "eslint-plugin-nuxt": ">=0.4.2"
  }
}

```

# 動作確認（とりあえずデフォでOK）
<img width="1680" alt="スクリーンショット 2019-09-29 9.54.52.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303093/b995ec32-abf8-a039-7278-c4b07a247af3.jpeg">


# 学習で使うデータを作る
[JSONPlaceholder](https://jsonplaceholder.typicode.com/)というWebサービスを使用。実際の実務でもデータを用意するコストを省くことができる。

- 今回はusers/のデータで実施する
<img width="1680" alt="スクリーンショット 2019-09-29 9.59.03.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303093/cdbf0e2d-e6ee-fc3c-beb4-563144f496b3.jpeg">

- 以下のURLでアクセスすると擬似的なusersのデータを取得できる

https://jsonplaceholder.typicode.com/users

<img width="1680" alt="スクリーンショット 2019-09-29 10.01.18.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303093/afea0dbb-9f01-caeb-f72d-33e41945b0f3.jpeg">

# データを取得して表示する

- index.vueの余計な箇所を削除し先ほどのurlから単純にデータを取得し表示（以下のようになっていればOKでstyleタグは削除）

```vue:index.vue
<template>
  <div class="container">
    <div>
      {{ users }}
    </div>
  </div>
</template>

<script>
const axios = require('axios')
const url = 'https://jsonplaceholder.typicode.com/users'

export default {
  asyncData ({ params }) {  //コンポーネントを初期化する前に非同期処理を行えるようにするメソッド
    return axios.get(url) //apiからのデータ取得をリクエスト
      .then((res) => {  //thenはレスポンスを受け取った段階で呼ばれるメソッド(res)にはレスポンスデータが入っている
        return { users: res.data } //res.dataにはjsonオブジェクトが入っている
      })
  }
}
</script>

```

- 結果
<img width="1680" alt="スクリーンショット 2019-09-29 10.21.26.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303093/f350d9c0-86bf-0019-24ac-8dc55554c64c.jpeg">



# 1人分のデータを取り出して表示する
- 考え方
  - 配列となっているためインデックスを指定したりキーを指定したりするだけ

```javascript:index.vue
{{ users[0] }}
```
とか

```javascript:index.vue
{{ users[0].id }},{{ users[0].name }}
```
とか

- 結果
<img width="1068" alt="スクリーンショット 2019-09-29 10.39.39.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303093/35c70bdc-9858-c5e7-bae1-92369cb91c1c.jpeg">


# v-forで複数のデータをリストで表示する。
- 考え方
  - v-forを使う

```javascript:index.vue
<!--{{ users[0].id }},{{ users[0].name }}-->
      <ul>
        <li v-for="user in users" :key="user.id">
          {{ user.id }},{{ user.name }}
        </li>
      </ul>
```

- 結果
<img width="1157" alt="スクリーンショット 2019-09-29 10.45.17.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303093/779f6207-75ed-6cdd-9c0f-07b27e948f6b.jpeg">


# エラーハンドリング
- 状況
  - 404エラーが発生したとする

- `index.vue`内のurlを存在しないurlへ変更
  - 例）`const url = 'https://jsonplaceholder.typicode.com/usersxxx'`

- 考え方
  - 引数に`error`を入れて`catchメソッド`で処理する

```javascript:index.vue
export default {
  asyncData({ params, error }) {
    return axios.get(url) 
      .then((res) => {
        return { users: res.data }
      })
      .catch((e => {
        //errorメソッドにはステータスコードと表示するメッセージを指定する
        error({ users: e.response.status, message: '404Error!!!!!' })
      }))
  }
}
```

# とりあえず以上です。