KAEDE Hack blog

JavaScript 中心に ライブラリなどの使い方を解説する技術ブログ。

Nuxt Axios で ~/static/ のファイルと json place holder のサンプルデータを get する

参考

Vue.js Nuxt.js 超入門

Chapter-6 外部サービスを利用しよう

why

書籍にあったから使えるように理解しておく

axios を入れる

shimablogs.com

axios とは、http 通信を非同期で行えるライブラリ

400 や 500 のエラーを reject してくれるらしい。

npm i axios で入る。

axios で README.md を取ってきて表示する

Page 353

pages/axios.vue を作成

<template>
  <section>
    <h1>{{ title }}</h1>
    <p> {{ message }} </p>
    <pre> {{ html_data }} </pre>
  </section>
</template>

titie, message, そして html_data を表示する template を作成

<script>
import axios from 'axios'
const url = "/README.md"

export default {
  data: () => {
    return {
      title: 'Axios',
      message: 'this is axios sample',
    }
  },
  asyncData: async function() {
    let result = await axios.get(url)
    return { html_data: result.data }
  }
}
</script>

axios を入れて、 README.md の場所を指定して

data に title と message を定義

asyncData というものを直接定義し、html_data に get した結果を返す

f:id:kei_s_lifehack:20210822234439p:plain

しかし、これで実行しても asyncData のところがエラーを返す。


computed で作って試すが await がない

  computed: {
    getReadME() {
      const result = await axios.get(url)
      return result.data
    }
  },

手慣れた computed で計算させて関数を定義

普通に return で返す

    <pre> {{ getReadME() }} </pre>

普通に 呼び出してみる

Error
Module build failed (from ./node_modules/babel-loader/lib/index.js): 
SyntaxError: /Users/kaede/code/fb-nuxt/pages/axios.vue: 
Unexpected reserved word 'await'. (22:21) 
[0m [90m 20 |[39m computed[33m:
[39m {[0m [0m [90m 21 |[39m getReadME()

予約後である await は使えないエラーが出た

なのでこれは没。computed で axios を使うのはいずれまとめる。

SSR モードを解除して解決

stackoverflow.com

ググると、 SPA モードになってないかららしい?

誘導リンクの通りに

nuxt.config.js に

ssr: false,

を追加したら解決した。

f:id:kei_s_lifehack:20210822235851p:plain

これで (assets)/README.md を表示することができた

当然パーサーは通ってないので html に変換されたりはしてない。

data と並列で component で書くやり方の詳細を見る

axios.nuxtjs.org

axios nuxt の公式を見ると

computed や method に書かずに、data と並列で定義する

  asyncData: async function() {
    let result = await axios.get(url)
    return { html_data: result.data }
  }

このやり方は component を作っているらしい。

今は asyncData のコンポーネントに頼ることにする


JSON Place Holder のサンプルデータを取る

Page 358

jsonplaceholder.typicode.com

JSON Place Holder という、REST API のサンプルがある

jsonplaceholder.typicode.com

posts も取れる。

https://jsonplaceholder.typicode.com/posts

この URL を使う。

これで userID, id, title, body, を表示するサンプルをつくる

  asyncData: async function() {
    let id = 1
    let result = await axios.get(url + '/' + id)
    return { json_data: result.data }
  },

先ほどの自動で実行される非同期の関数で

json placeholder の url に仮で id に 1 を足し

json_data を返すようにする

なお、テキストでは + '/' が抜けていたのでそのまま実行するとエラーになる。

    <h2> {{ json_data.id }} </h2>
    <h2> {{ json_data.title }} </h2>
    <h2> {{ json_data.body }} </h2>

そして template で id, title, body を表示

f:id:kei_s_lifehack:20210823025114p:plain

これで post id 1 の内容が取れた

f:id:kei_s_lifehack:20210823030315p:plain

id を 10 にしても id 10 の内容が取れた

input に入れた id のデータを btn 押したときに表示する

<input type="text" v-model="finder">
<button @click="getInputIdData"> find </button>

finder を作成

get input id data の関数を btn に連携

  data: function() {
    return {
      json_data: {},
      finder : "",
    }
  },

json_data を 空の object で data に定義

finder を空の文字列で定義

  methods: {
    getInputIdData: function(event) {
      axios.get(url + '/' + this.finder)
        .then( (res) => {
          this.json_data = res.data
        })
    }
  },

入力値を取得する関数を作る。

axios.get で url + / + this.finder

この this.finder というのは

v-model によって input から取ってきた finder に this でアクセスしている。

そして、そこに .then で レスポンスを持ってきて、そのデータを

this でアクセスした json_data に入れている。

f:id:kei_s_lifehack:20210823033509p:plain

これによって input に入れた値で ボタンを押したときに

axios で取ってこれるように組めた。

エラー時の例外処理。

このままだとレスポンスがない時にわかりにくい。

なので .catch を使った例外処理を書く。

    getInputIdData: function(event) {
      axios.get(url + this.finder)
        .then( (res) => {
          this.json_data = res.data
          this.message = 'get ID: ' + this.finder 
        }).catch((error) => {
      this.message = 'ERR'
      })
    }

こうやって、.then の後に .catch( ( error) => { } )を繋げて、

レスポンスがなかったときにメッセージにエラーを入れられるようにした


まとめ

最初に 静的データを非同期でとってきて表示するだけなら、

  asyncData: async function() {
    let result = await axios.get(url)
    return { html_data: result.data }
  }

data に並列させてそのコンポーネントを作るだけいける。

また外部のでも同じようにいける

ただ、ボタンで発火させるには

  methods: {
    getInputIdData: function(event) {
      axios.get(url + '/' + this.finder)
        .then( (res) => {
          this.json_data = res.data
        })
    }
  },

get() の後ろに .then をつけて、this でアクセスした data に入れる必要がある