【Vue】Loading画面の実装方法を✅
脚に鉄アレイ入ってる?胸Bカップくらいある?と彼女に言われてすごく上機嫌な23期酒ケジュール作成中です。
進捗
多少の進捗あり!
SSLとは
WebブラウザとWebサーバー間においてデータのやりとりを暗号化させる技術。Secure Socket Layerの略。
クレジットカード情報や個人情報などの秘匿情報が外部に漏れたり、ハッキングされたりすることを防ぐ。
SSL対応のサイトには、webブラウザの左側に南京錠マークが出る。また、http://ではなく、https://になることも特徴とされている。
SSLの仕組み|情報セキュリティ関連の技術|基礎知識|国民のための情報セキュリティサイト
さて、今回はVue.jsを使ったアプリに「いい感じのloading中画面」とつける方法を学習していきたいと思います。
Loading画面とは
データを取ってくるまで表示させておく画面
サークルやボール、サイクロンなどの種類がある。決済中画面や電波の悪いときによく見る。
これって、画面がフリーズしてるの?それとも待ち時間なの?とユーザーを困惑させないための配慮として使われたりする。
$ yarn add vue-loading-template
main.js
import Vue from 'vue';
import App from '../App';
import VueLoading from 'vue-loading-template';
Vue.use(VueLoading /** options **/);
これだけでもう使用できてしまう。
次に、ローディングを付与させたい画面に下記コンポーネントを記述する。
<VueLoading
type="cylon"
color="#d9544e"
:size="{ width: '50px', height: '50px' }"
></VueLoading>
任意でカスタマイズする事ができる
type:
ローディングの種類を変更させる事ができる。
cyclon
<VueLoading
type="cylon"
color="#d9544e"
:size="{ width: '50px', height: '50px' }"
></VueLoading>
spiningDubbles
<VueLoading
type="spiningDubbles"
color="#d9544e"
:size="{ width: '50px', height: '50px' }"
></VueLoading>
spin
<VueLoading
type="spin"
color="#d9544e"
:size="{ width: '50px', height: '50px' }"
></VueLoading>
color:
任意の色にする事ができる
#000
<VueLoading
type="spin"
color="rgb(0,0,0)"
:size="{ width: '50px', height: '50px' }"
></VueLoading>
[![Image from Gyazo](<https://i.gyazo.com/22214020b89ad57f3929872315c6db83.gif>)](<https://gyazo.com/22214020b89ad57f3929872315c6db83>)
size:
ローディング中画面の大きさを変更する事ができる
<VueLoading
type="spin"
color="rgb(0,0,0)"
:size="{ width: '200px', height: '50px' }"
></VueLoading>
全体像
もしloadingCircleがtrueだった場合、VueLoadingが表示され、falseだった場合、酒ケジュールが表示されるようにしている。
frontend/components/result/ShowShucheduleModal.vue
<div class="text-center black--text outer-layer" style="white--text">
<div v-if="loadingCircle">
<VueLoading
type="cylon"
color="#d9544e"
:size="{ width: '50px', height: '50px' }"
></VueLoading>
</div>
<div v-else>
<img :src="drunknessEagerToImg" width="50" height="50" />
</div>
<span class="mb-6 text-center">への 酒ケジュール</span>
</div>
<br />
<div v-if="loadingCircle">
<VueLoading
type="spiningDubbles"
color="#d9544e"
:size="{ width: '200px', height: '50px' }"
></VueLoading>
</div>
<div v-else>
<v-row justify="center" align-content="center">
<v-col
v-for="data in alcoholItems"
:key="data.id"
class="justify-space-between outer-layer"
>
<v-icon>{{
data.alcohol_percentage === 0 ? 'mdi-cup' : 'mdi-glass-mug'
}}</v-icon>
<p>
{{ data.name }}
</p>
<p>{{ data.alcohol_percentage }}%</p>
<p>{{ data.alcohol_amount }}ml</p>
</v-col>
</v-row>
</div>
<template>
</template>
<script>
import { VueLoading } from 'vue-loading-template';
export default {
props: {
alcoholDatas: {
type: Array,
},
loadingCircle: {
type: Boolean,
},
},
components: {
VueLoading,
},
computed: {
alcoholItems() {
const targetAlcohols = (this.alcohols = this.alcoholDatas);
return targetAlcohols;
},
},
}
</script>
v-ifを使用し、loadingCircleがtrueの場合、VueLoadingが表示され、それ以外はfalseになるようにした。
loadingCircleがfalseになるタイミングは、親コンポーネントがapiを叩いてデータを取ってくることが成功したタイミングになっている。
frontend/pages/Result.vue
<template>
<div>
<ShowShucheduleModal
v-if="showShuchedule"
:alcoholDatas="alcoholContents"
:loadingCircle="loading"
:motivationImg="nextMotivationImg"
@twitterShare="snsUrl"
@closeModal="closeShucheduleModal"
/>
<div>
</div>
</template>
<script>
import { mapActions, mapGetters, mapMutations } from 'vuex';
export default {
components: {
ShowShucheduleModal,
},
data(){
loading: true,
},
created() {
axios
.get('/alcohols')
.then((alcoholResponse) => {
this.alcohols = alcoholResponse.data;
return this.alcohols;
})
.then((alcohols) => {
this.loading = false; ←ここでloadingをfalseにしている
const thisAnalyze = this.analyzes;
const targetValues = alcohols;
const analyzeShuchedule = thisAnalyze[thisAnalyze.length - 1]['shuchedule'];
const contentsOfTarget = Object.values(targetValues)[analyzeShuchedule];
this.alcoholOrders = contentsOfTarget;
this.alcoholContents = contentsOfTarget;
});
},
}
</script>
親子コンポーネントに分けているため、少々見づらいかもしれない。
ライフサイフルフックのcreatedメソッドの中にapiを叩く処理を記述することで、mountedに書いたときに比べてサーバーに対する負荷を軽減される。
非同期処理に順番をつける(Promise構文)axiosにより、alcoholsパスからalcoholを取得した後(.thenの中身)this.loadingがfalseになるように書いた。
このように記述することで、お酒の種類を取ってくるまではloadingをtrueにしておく事が可能になった。
完成図
<div v-if="loadingCircle">
<VueLoading
type="spiningDubbles"
color="#d9544e"
:size="{ width: '200px', height: '50px' }"
></VueLoading>
</div>
<div v-else>
<v-row justify="center" align-content="center">
<v-col
v-for="data in alcoholItems"
:key="data.id"
class="justify-space-between outer-layer"
>
<v-icon>{{
data.alcohol_percentage === 0 ? 'mdi-cup' : 'mdi-glass-mug'
}}</v-icon>
<p>
{{ data.name }}
</p>
<p>{{ data.alcohol_percentage }}%</p>
<p>{{ data.alcohol_amount }}ml</p>
</v-col>
</v-row>
</div>