Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
73
Help us understand the problem. What is going on with this article?
@yakiniku0220

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

More than 1 year has passed since last update.

業務で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

73
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
yakiniku0220
最近はReact Native触ってます。 VueやNuxt.jsなどが好きです。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
73
Help us understand the problem. What is going on with this article?