Nuxt.js + Buefyでローディング画像を表示する

公開日:2019/10/10 更新日:2019/10/10
Nuxt.js + Buefyでローディング画像を表示するのサムネイル

はじめに

Nuxt.jsでBuefyを使っている前提となりますが、axiosで何かしらのファイルをダウンロードしている間などユーザに処理中であることを示すためにローディング画像を表示するよう実装しました。その手順をまとめます。非常に簡単に実装できます。Buefyについては以下をご覧ください。

www.virment.com

BuefyはBulmaというUIコンポーネントセットをベースにしたVue.js用のUIコンポーネントセットです。Bootstrapのようにあらかじめ用意されたHTMLタグやCSSクラスを使うことで簡単にそれなりの見た目になります。ここでは、Vue.jsアプリでBuefyを使えるようにするための準備手順と、最後にmarginやpadding用のクラスをBuefyに追加する方法をメモします。

できるようになること

以下のGIF画像のように、ファイルのダウンロードボタンをクリックすると、ダウンロードが完了するまでぐるぐるとローディング画像が表示されます。

nuxt-buefy-loading-demo.gif

前提と環境

ここでは、Nuxt.jsにてnuxt-buefyをインストールして使っている前提ですが、おそらくVue.jsや他のコンポーネントセットでも対応を見れば分かると思います。

  • Nuxt.js : 2.9.0
  • nuxt-buefy: 0.3.14
`nuxt-buefy`の公式リポジトリは以下です。
github.com

It's really very simple to start with nuxt. But we can make it even simpler by adding nuxt-buefy.

ストア側の処理

まず、ストア側のコードを以下に載せます。以下はstore/file.jsというストアを適当に用意しています。

store/file.js
import axios from 'axios'

export const state = () => ({
  loading: false, // ローディング中を表すストア

  // (...省略...)
})

export const mutations = {

  // (...省略...)

  updateLoading (state, value) {
    state.loading = value
  },

  // (...省略...)
}

export const actions = {
  
  // (...省略...)

  // axiosを使ってファイルをダウンロードするアクション
  async downloadFile ({ state, commit }) {
    // ローディングを表示する
    commit('updateLoading', true)
    await axios
      .get('https://yourwebsite/file')
      .then((response) => {
        // ダウンロードが完了した時の処理
      })
      .catch((error) => {
        // エラー発生時の処理
      })
      .finally(() => {
        // ローディングを非常時にする
        commit('updateLoading', false)
      })
   
  }

  // (...省略...)

}

上記のコードは、axiosを使用して何かしらのWebサイトやAPIからファイルをダウンロードする処理を含んでいます。そのaxiosの処理開始前にupdateLoadingでローディング画像を表示するフラグをtrueに設定し、axiosの処理が全て完了したらローディング画像を非表示にするためにfinallyの中でupdateLoadingfalseに設定しています。 あとは、このdownloadFileを使いたいコンポーネントファイルでローディング画像を表示するための記述を少しだけ追記します。

コンポーネントにローディング画像表示部分を追記する

以下のように<b-loading>というBuefyのローディング用のコンポーネントを追記します。

pages/download.vue
<template>
  <div class="home">
    <section>
      <div class="my-component">
      <!-- 何かしらの表示 -->
          <a
            class="button is-success is-medium"
            @click="downloadFile()"
          >ファイルをダウンロードする</a>
        <b-loading :is-full-page="isFullPage" :active.sync="isLoading" />
      </div>
    </section>
  </div>
</template>

<script>
import { mapActions } from 'vuex'

export default {
  name: 'File',
  data () {
    return {
      isFullPage: true, // ローディング画像をページ全体に表示するか、親要素に限定するかのフラグ
      // (...省略...)
    }
  },
  computed: {
    isLoading () {
      return this.$store.state.file.loading
    },
     // (...省略...)
  },
  methods: {
    ...mapActions({
      downloadFile: 'file/downloadFile'
    }),
    // (...省略...)
  }
}
</script>

上記で追加している要素は以下です。

  • <b-loading :is-full-page="isFullPage" :active.sync="isLoading" />

Buefyのローディング画像表示用のコンポーネント。is-full-pagetrueならばローディング画像をページ全体に表示、falseならば<b-loading>の親要素内でローディング画像を表示する。

  • isLoading ()でストアのローディング状態を表すストア変数loadingを監視
  • ...mapActionsdownloadFileをコンポーネントファイル内で使えるようにする

まとめ

Buefy頼りなところもありますが、とても簡単に実装できます。

開発アプリ

nanolog.app

毎日の小さな出来事をなんでも記録して、ログとして残すためのライフログアプリです。