くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

vue-infinite-loadingでNuxt.jsでも無限スクロール

無限スクロールしたいなぁと思ったら、
vue-infinite-loadingという便利があったので、その時の備忘録。

準備する

インストール

$ npm i --save vue-infinite-loading

pluginの作成

plugins/vue-infinite-loading.tsを用意

import Vue from "vue";
import InfiniteLoading from "vue-infinite-loading";

Vue.use(InfiniteLoading);

nuxt.config.tsの設定

作ったpluginを追加する。

const config: NuxtConfiguration = {
  plugins: [
    { src: "~/plugins/vue-infinite-loading", ssr: false },
  ],
}

つかってみる

シンプルにはこんな感じ。

  1. リストの最後にinfinite-loadingを追加して、
  2. リストの一番下に来たら、@infinite="infiniteHandler"が発火
  3. infiniteHandler()で次を読み込んで、itemsに追加
<template>
  <div>
    <template v-for="item in items">
      <!-- リストとして表示するなにか -->
    </template>
    
    <infinite-loading :identifier="identifier" @infinite="infiniteHandler">
      <!-- slotでメッセージをカスタマイズできる -->
      <div slot="no-more">もう読み込めないときのメッセージ</div>
      <div slot="no-results">結果がないときのメッセージ</div>
    </infinite-loading>
  </div>
</template>

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

@Component
export default class extends Vue {
  items: any[] = []
  identifier: number = 1
  loading: boolean = false;
  
  async infiniteHandler($state: any) {
    if (this.loading) return; // 読み込み中ならスキップ
    
    try {
      this.loading = false;
      const res = await this.$axios.get("...");
      this.items.push(...res);
      
      // 読み込みが終わって、まだ読み込めればloaded()を呼ぶ
      $state.loaded();
    } catch(error) {
      // もう読み込めなければcomplete()を呼ぶ
      $state.complete();
    } finally {
      this.loading = false;
    }
  } 
}

infiniteHandlerが呼ばれたあとに、

  • 読み込みが完了して、まだ読み込めるものがあれば、loaded()を呼ぶ
  • もう読み込むものがない場合は、complete()を呼ぶ

ハマった点

infiniteHandlerが無限に呼ばれる

ローディングが長いと、何度もinfiniteHandlerが呼ばれる。。
なので、loading変数を用意して、読み込み中のときはスキップするようにした。

$state.complete()したあとに、リセットしたい

エラーや全部読み込んだあとに、$state.complete()を呼ぶと、
もう一度読み込み直すときに、infiniteHandlerが呼ばれなくなる。。

リセットする必要があるっぽく、propsのidentifierを更新すると、resetされるっぽい。

必要に応じて、this.identifier += 1;すればOK

以上!!

参考になる書籍

Nuxt.jsビギナーズガイド―Vue.js ベースのフレームワークによるシングルページアプリケーション開発

Nuxt.jsビギナーズガイド―Vue.js ベースのフレームワークによるシングルページアプリケーション開発

Vue.js入門 基礎から実践アプリケーション開発まで

Vue.js入門 基礎から実践アプリケーション開発まで

基礎から学ぶ Vue.js

基礎から学ぶ Vue.js

改訂新版 Vue.jsとFirebaseで作るミニWebサービス (技術の泉シリーズ(NextPublishing))

改訂新版 Vue.jsとFirebaseで作るミニWebサービス (技術の泉シリーズ(NextPublishing))

参考にしたサイト様