Vue.js入門第8回。Vue.jsで非同期通信を行う方法をまとめたいと思います。
はじめに
ユーザビリティ向上やSPAなどで非同期通信(ajax)は頻繁に用いられますが、今回はVue.jsで非同期通信を使ってビットコインの価格を表示してみたいと思います。
非同期通信を実現するためにaxios(アキシオス)というライブラリを使用します。axiosはVue公式サイトも推奨しているライブラリです。
ビットコイン価格の取得は会員登録なしで利用できるcoindeskのAPIを使います。
レスポンスの内容はこちらから確認できます。
ソースコード
解説
Javascript
まずはJavascriptから解説します。
new Vue({
el: '#app',
data: {
bpi: null,
hasError: false,
loading: true
},
})
dataプロパティに以下の3つを定義します。
- ビットコインの情報を保持するbpi
- APIエラー制御用のhasErrorフラグ
- API呼び出し中の制御用のloadingフラグ
new Vue({
・
・
mounted: function() {
axios.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(function(response) {
// console.log(response.data.bpi);
this.bpi = response.data.bpi
}.bind(this))
.catch(function(error) {
console.log(error)
this.hasError = true
}.bind(this))
.finally(function() {
this.loading = false;
}.bind(this))
},
})
mountedプロパティ(mountedイベント通知時)にaxiosを使ってビットコインの現在の価格を取得しています。
mountedはVueの初期化が完了したタイミングで通知されます。詳細は公式サイトで解説されているので確認してみてください。
thenメソッド内には正常終了時の処理を書きます。bpiプロパティにレスポンスを設定しています。なお、無名関数内でVueのプロパティにアクセスできるようにbindでインスタンスを置き換えています。
catchメソッドにはエラーが発生した際の処理を書きます。hasErrorプロパティをtrueにしています。
finallyメソッド内にはAPI呼び出し後に必ず行う処理を書きます。loadingプロパティをfalseにしています。
new Vue({
・
・
filters: {
currencyDecimal(value) {
return value.toFixed(2)
}
}
})
filtersプロパティにcurrencyDecimalメソッドを定義しています。toFixedメソッドを使って引数のvalueの値を小数第二位の値に丸めています。
filtersで定義した関数はHTMLにバインドする際に指定することが出来ます。
HTML
<div>
<section v-if="hasError">
Error.
</section>
<section v-else>
・
・
</section>
</div>
HTMLではhasErrorプロパティがtrueの場合はError.と表示し、それ以外の場合は後述するHTMLを描画します。
つまりAPI呼び出しでエラーが発生した際は「Error.」と表示されるようにしています。
<section v-else>
<div v-if="loading">
Loading..
</div>
<div v-else>
<ul v-cloak>
<li v-for="(rate, currency) in bpi">
{{ currency }} : {{ rate.rate_float | currencyDecimal}}
</li>
</ul>
</div>
</section>
hasErrorプロパティがfalseの場合はさらに分岐をし、loadingプロパティがtrueであれば「Loading.」と表示します。
API呼び出し中は「Loading.」と表示されるようにしています。
それ以外の場合はAPI呼び出しで取得したビットコインの価格情報をv-forディレクティブを使って一覧表示しています。
その際に、「|」(パイプ)でcurrencyDecimalフィルターを指定して、価格が小数第二位まで表示されるようにしています。
また、v-cloakディレクティブを指定しています。詳細は別の記事にまとめます。
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.18.0/dist/axios.min.js"></script>
vueとaxiosの読み込みを行なっています。