Nuxt Axios で ~/static/ のファイルと json place holder のサンプルデータを get する
参考
Vue.js Nuxt.js 超入門
Chapter-6 外部サービスを利用しよう
why
書籍にあったから使えるように理解しておく
axios を入れる
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 した結果を返す
しかし、これで実行しても 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 モードを解除して解決
ググると、 SPA モードになってないかららしい?
誘導リンクの通りに
nuxt.config.js に
ssr: false,
を追加したら解決した。
これで (assets)/README.md を表示することができた
当然パーサーは通ってないので html に変換されたりはしてない。
data と並列で component で書くやり方の詳細を見る
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
JSON Place Holder という、REST API のサンプルがある
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 を表示
これで post id 1 の内容が取れた
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 に入れている。
これによって 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 に入れる必要がある