Nuxt.jsでローディング(Loading)画面を実装する!

nuxt.js Nuxt.js

Nuxt.jsでローディング(Loading)画面を実装する

掲示板アプリでローディング画面を作成しました。
ローディングは通信中にユーザーに待機してもらうための画面になります。

本記事ではローディング画面を使う方法と独自のローディング画面の実装方法について記載しています。

Nuxt.jsでローディングを表示するには

Nuxt.jsには標準でローディングを表示する機能が備わっています。

これは画面上部に表示されるプログレスバーのようなものです。
こんな感じで、画面上部に左から右にプログレスバーのようなものが動きます。

任意の箇所で、下記を呼び出すと表示されます。

this.$nuxt.$loading.start();

処理を終わりたい箇所で、下記のように記載すると止まります。

this.$nuxt.$loading.finish();

標準だとわかりにくいため、わかりやすくするために独自のローディング処理を実装してみました。

独自のローディング処理を実装する

今回はグルグル回るローディングを実装してみました。
Loadingコンポーネントを作成して、nuxt.config.jsに設定を入れると実装できます。

コンポーネントのサンプルコード

components/Loading.vueを作成します。コードは下記のようになります。

<template lang="html">
  <div class="loader-background" v-if="loading">
    <div class="loader"></div>
  </div>
</template>

<script>
  export default {
    data: () => ({
      loading: false
    }),
    methods: {
      start() {
        this.loading = true
      },
      finish() {
        this.loading = false
      }
    }
  }
</script>

<style scoped>
.loader-background {
  z-index: 99;
  position: fixed;
  background:#0a0a0a;
  opacity: 0.4;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.loader {
  color: #ffffff;
  font-size: 20px;
  margin: 100px auto;
  width: 1em;
  height: 1em;
  border-radius: 50%;
  position: relative;
  -webkit-animation: load4 1.3s infinite linear;
  animation: load4 1.3s infinite linear;
  -webkit-transform: translateZ(0);
  -ms-transform: translateZ(0);
  transform: translateZ(0);
}
@-webkit-keyframes load4 {
  0%,
  100% {
    box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
  }
  12.5% {
    box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
  }
  25% {
    box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
  }
  37.5% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
  }
  50% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
  }
  62.5% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
  }
  75% {
    box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
  }
  87.5% {
    box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
  }
}
@keyframes load4 {
  0%,
  100% {
    box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
  }
  12.5% {
    box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
  }
  25% {
    box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
  }
  37.5% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
  }
  50% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
  }
  62.5% {
    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
  }
  75% {
    box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
  }
  87.5% {
    box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
  }
}
</style>

TypeScriptで書く場合のサンプルコード

scriptの箇所をtypescriptで書く場合は下記のようにします。

<script lang="ts">
import { Component, Prop, Vue } from 'nuxt-property-decorator';

@Component({
  name: 'Loading',
})
export default class Loading extends Vue {
  @Prop()
  private loading: boolean = false;

  private start() {
    this.loading = true;
  }

  private finish() {
    this.loading = false;
  }
}
</script>

解説

templateタグの箇所に表示される内容を記載します。
ローディング画面のタグを記載しています。
タグの最初の方にv-if="loading"という記述があり、loadingプロパティがtrueだったら表示されます。

scriptタグにはコンポーネントの処理を書いています。
シンプルな内容で、loadingプロパティを持っていて、startならtrue, finishならfalseとしています。
startが呼ばれたらtrueになって表示される感じですね。

styleタグにはLoadingを表示する画面のCSSとアニメーションするCSSを定義しています。

nuxt.config.jsを修正する

nuxtの設定ファイルの項目にloadingプロパティを用意して、作成したコンポーネントまでのパスを設定すればOKです。

loading: './components/Loading.vue'

あとは、同じように

this.$nuxt.$loading.start();this.$nuxt.$loading.finish();を呼び出して使用できます。

動作確認する

今回実装したローディングの挙動ですが、こんな感じになります。

参考

コメント

タイトルとURLをコピーしました