【Nuxt.js】ローディング画面を実装する方法

こんにちは!CODE CLUB965のKです!

今回は、Nuxt.jsでローディング画面を実装する方法を紹介したいと思います。

サーバーと通信が発生したときに画面が止まっていると、ユーザーは「あれ?画面が固まった!」となってしまうので、そんなときにローディングを使います。

ちなみに、Nuxt.jsって何?という方は、公式サイトを見たら大体わかると思います。
https://ja.nuxtjs.org/

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

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

ですが、画面上部に表示されるプログレスバーのようなものです。
みなさんが想像しているローディングとは少し違うと思います。

ちなみに、標準のまま使うのであれば、ローディングを呼び出したい箇所で

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


を呼び出し、ローディングを終了したい箇所で

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

を呼び出すだけです。

グルグル回るローディングを実装する

以下に一般的なみなさんがよく見るローディングのサンプルコードを書いておきます。

コンポーネント内にLoading.vueを作成する

まずは、Loding.vueというファイルをcomponents内に作成して下さい。

そして、ファイル内に以下のコードを記述します。
※ typescriptで記述しています。

■ Loding.vue

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

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

@Component
export default class Loading extends Vue {
  @Prop({ type: Boolean, default: false })
  type!: Boolean

  private loading: boolean = false;

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

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

<style lang="scss" scoped>
@import './style.scss';
</style>

templateタグに表示される内容を記載します。
タグの最初に「v-if="loading"」と記述していますが、これは、loadingプロパティがtrueだったらローディングを表示するという意味です。

scriptタグの中身は、コンポーネントの処理を書きます。
特に難しくはなく、loadingプロパティが、startならtrueでローディングを表示し、finishならfalseでローディングが非表示となります。

styleタグでは、scssファイルで定義したアニメーションを読み込んでいます。

scssファイルでローディングのアニメーションを定義する

上記で処理的なところはできたので、あとはローディングのアニメーションを記述します。

以下にコードを書きますが、好みのデザインに修正して使って下さい。
ちなみにIEでもちゃんと動きました。(IE考慮していないと、たまにデザイン崩れしますよね..)

■ style.scss

.loader-background {
  z-index: 99;
  position: fixed;
  left: 0;
  top: 0;
  background:#0a0a0a;
  opacity: 0.4;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.loader {
  color: #ffffff;
  font-size: 20px;
  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;
  }
}

これでOKと言いたいところですが、最後にひとつだけやることがあります。

nuxt.config.jsにパスを設定する

最後に「nuxt.config.js」内に作成したコンポーネントまでのパスを記述します。

loading: './components/Loading.vue'

あとは、ローディングを呼び出す箇所と終わる箇所に、「this.$nuxt.$loading.start();」と「this.$nuxt.$loading.finish();」を記述すればローディング機能の追加は完了です!

これでクルクル回るローディングが画面に表示されます。

最後に

今回は、Nuxt.jsでローディング画面を実装する方法を紹介しました。

アプリやサイトを作成すればローディングの表示は使うと思いますので、ぜひ参考にして下さい。

それでは、また!

Follow me!