12
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue.jsでFacebookのようなローディングを表示する [vue-content-loaderの紹介]

Last updated at Posted at 2019-01-13

FacebookやYoutubeなどで最近良く見かけるコンテンツローダーを手軽に実装できるvue-content-loaderの紹介です。
簡単に導入できてSPAぽいリッチな表現ができるのでおすすめです。

以下のようなものを作成します。
(GIFの都合上カクついてますが、実際はもっとなめらかです。)
Jan-13-2019 17-52-20 (1).gif

vue-content-loaderのインストール

https://github.com/egoist/vue-content-loader
を利用します。Reactにあるreact-content-loaderのvue版のようです、
Vueプロジェクト上で、パッケージを追加します。

$ yarn add vue-content-loader

実装サンプル

あとは、importして使うだけです。
LoadingBlogSectionコンポーネントというものを作成します。
見栄えを整えるため、vuetify (https://vuetifyjs.com/en) を使っています。

LoadingBlogSection.vue

<template lang="pug">
  v-container(grid-list-lg fluid pa-0)
    v-layout(row wrap)
      v-flex(v-for="n in 4" :key="n" xs12 md3)
        v-card
          content-loader(:width="300" :height="300")
            rect(width="100%" height="150")
            rect(y="180" x="15" width="150" height="20")
            rect(y="220" x="15" width="200" height="10")
            rect(y="240" x="15" width="250" height="10")
            rect(y="260" x="15" width="150" height="10")
            rect(y="280" x="15" width="250" height="10")
</template>

<script>
import { ContentLoader } from 'vue-content-loader'

export default {
  components: {
    ContentLoader
  }
}
</script>

以下部分でContentLoaderの読み込みと、componentsへの登録を行います。

<script>
import { ContentLoader } from 'vue-content-loader'

export default {
  components: {
    ContentLoader
  }
}
</script>

次にLoader表示部分です。
content-loader内部のrectというコンポーネントで四角のSVGを表示しています。
yが上部からの絶対位置、xが左部からの絶対位置です。

<template lang="pug">
...
        v-card
          content-loader(:width="300" :height="300")
            rect(width="100%" height="150")
            rect(y="180" x="15" width="150" height="20")
            rect(y="220" x="15" width="200" height="10")
            rect(y="240" x="15" width="250" height="10")
            rect(y="260" x="15" width="150" height="10")
            rect(y="280" x="15" width="250" height="10")
...

これでローディング用のコンポーネントが出来たので、
あとは、v-ifでローディング状態を判定して、ローディング中のみ表示するようにすればOKです。
以下Apolloの例で、$apollo.loadingでローディング状態を判定しています。
BlogSectionがAjaxで取得したデータの表示用のコンポーネントです。

index.vue
<template lang="pug">
  v-content
    v-container
      h1(class="mb-5") vue-content-loader demo
      <!-- この部分でv-ifで判定して、表示を切り替えている -->
      BlogSection(:posts="posts" v-if="!$apollo.loading")
      LoadingBlogSection(v-if="$apollo.loading")
</template>

<script>
import { FETCH_POST_BY_LIMIT } from '@/apollo/query/posts'
import BlogSection from '@/components/BlogSection'
import LoadingBlogSection from '@/components/LoadingBlogSection'

const POSTS_LIMIT = 4

export default {
  components: {
    BlogSection,
    LoadingBlogSection
  },
  apollo: {
    posts: {
      query: FETCH_POST_BY_LIMIT,
      variables () {
        return {
          first: POSTS_LIMIT
        }
      }
    }
  }
}
</script>

これで完成です。

参考: ローディングのSVGをGUIで調整する

svgで表示する部分は、以下サイトにてGUI上で調整が行えます。
https://create-vue-content-loader.netlify.com/
完了したら、左ペインのコードをコピペして使ってください。

スクリーンショット 2019-01-13 17.54.39.png
12
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?