LoginSignup
91
77

More than 5 years have passed since last update.

Nuxt.jsとvue-infinite-loadingを使って無限スクロールを実装する

Last updated at Posted at 2019-02-19

業務でvue-inifinite-loadingというプラグインを使う機会があったので、今回はNuxt.jsとvue-inifinite-loadingを使って無限スクロールを実装してみました。

事前準備

まずvue-inifinite-loadingのプラグインをインストールします。

npm install vue-infinite-loading -S
or
yarn add vue-infinite-loading

次にplugins/infiniteloading.jsに以下を追加します。

plugin/infiniteloading.js
import Vue from 'vue'
import InfiniteLoading from 'vue-infinite-loading'

Vue.component('infinite-loading', InfiniteLoading)

最後にnuxt.config.jsのpluginに先ほど作成したファイルを追記します。

nuxt.config.js
plugins: [
  { src: '~/plugins/infiniteloading', ssr: false }
]

初期設定はこれで終わりです。

実際に使ってみる

DEMO

今回作ったデモはこちらです。
簡単なデモですが、リストを作って一定数スクロールすると読み込み処理が走って、続きのリストが表示されるようになっています。
infinitescroll.gif

コード

実際のコードはこちらです。

components/InfiniteScroll.vue
<template>
  <div class="infinite-scroll">
    <ul class="infinite-scroll-list">
      <li class="infinite-scroll-list-item" v-for="i in this.count" :key="i">scroll {{ i }}</li>
    </ul>
    <infinite-loading 
      ref="infiniteLoading" 
      spinner="spiral"
      @infinite="infiniteHandler">
      <div slot="no-results"/>
    </infinite-loading>
  </div>
</template>

<script>
export default {
  name: 'InfiniteScroll',
  data() {
    return {
      count: 20
    }
  },
  methods: {
    infiniteHandler() {
      setTimeout(() => {
        this.count += 20
        this.$refs.infiniteLoading.stateChanger.loaded()
      }, 1000)
    }
  }
}
</script>

<style>
.infinite-scroll {
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 680px;
  margin: 100px 0;
}

.infinite-scroll-list-item {
  height: 60px;
  margin: 10px 0;
  border-bottom: 1px solid #eaeaea;
  padding-bottom: 10px;
}
</style>

使用方法としては、templateにinfinite-loadingを使います。
@infiniteには作ったmethod名を記入します。
今回はinfiniteHandlerというメソッド名にしています。

次にメソッド内の処理についてです。

methods: {
  infiniteHandler() {
    setTimeout(() => {
      this.count += 20
      this.$refs.infiniteLoading.stateChanger.loaded()
    }, 1000)
  }
}

このメソッド内ではメソッドが読み込まれたらcount値を加算させ、this.$refs.infiniteLoading.stateChanger.loaded()の処理で再度ローディングの処理を行います。

読み込むデータがない場合の処理

DEMO

一定数スクロールをして、表示するデータがなくなった場合にNo more data :)という文字が表示されるようになっています。
infiniteloading_finish.gif

コード

methods: {
  infiniteHandler() {
    setTimeout(() => {
      if (this.count < 100) {
        this.count += 20
        this.$refs.infiniteLoading.stateChanger.loaded()
      } else {
        this.$refs.infiniteLoading.stateChanger.complete()
      }
    }, 1000)
  }
}

今回はNo more data :)という文字列を出すためにカウント値で条件を書いてますが、実際のリストとかならlengthを使って合計値を取り、加算されたcount数とで比較するといいかなと思います。

if (this.count < hogehoge.length) {
  this.count += 20
  this.$refs.infiniteLoading.stateChanger.loaded()
} else {
  this.$refs.infiniteLoading.stateChanger.complete()
}

デフォルトだと表示するデータが取得できなくなった場合No more data :)になっていますが、変更したい場合はtemplate側に<span slot="no-more">hogehoge</span>を書き込むと文言を変更することができます。

<infinite-loading 
  ref="infiniteLoading" 
  spinner="spiral"
  @infinite="infiniteHandler">
  <span slot="no-more">もうないよ</span>
</infinite-loading>

ローディングのカスタマイズ

このプラグインは便利なことにローディング時のspinerを変えることが可能です。
vue-infinite-loadingでは5つ用意されてます。

default

loading_default.gif

spiral

loading_spiner.gif

circle

loading_circle.gif

bubbles

loading_bubbles.gif

waveDots

loading_wavedots.gif

自分でカスタマイズしたローディングのspinerにするにはtemplate側に以下を追加するとできます。

<infinite-loading 
  ref="infiniteLoading" 
  @infinite="infiniteHandler">
  <div slot="spinner">
    <img src="hogehoge">
  </div>
</infinite-loading>

<div slot="spinner"></div>で囲み、その中に表示したい画像を入れると、その画像がspinerとして指定することが可能です。

まとめ

今回初めて無限スクロールをvue-infinite-loadingを使って実装してみましたが、すごい使いやすいプラグインでした。
ドキュメントもかなり分かりやすくまとめてあったので導入自体もそこまで時間がかからずにできました。
もじ無限スクロールを実装することがあったらオススメのプラグインなので使ってみてください。

今回作ったDEMOのコードはgithubに掲載しているので、vue-infinite-loadingを使う機会があったらご参照ください。
https://github.com/ebarakazuhiro/blog/tree/master/infinite_loading

91
77
1

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
91
77