はじめに

Vue.js で PeachScript/vue-infinite-loading を使った無限スクロール(Infinite Scroll)の実装方法。

TL;DR

  • npm i vue-infinite-loading でインストール
  • <infinite-loading @infinite="infiniteHandler" /> を記述
  • infinite イベントのハンドラ内でデータの追加や、読み込み完了などの処理を実施
この記事が参考になった方
ここここからチャージや購入してくれると嬉しいです(ブログ主へのプレゼントではなく、ご自身へのチャージ)
欲しいもの / Wish list

目次

  1. はじめに
  2. TL;DR
  3. 環境・条件
  4. 詳細
    1. セットアップ
    2. 使い方
      1. 基本
      2. 無限スクロールをリセットしたい
      3. 下から上にスクロールさせたい
      4. メッセージを変更したい
  5. まとめ
  6. その他・メモ
  7. 参考文献

環境・条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.6
BuildVersion: 19G73

$ node -v
v12.7.0

$ npm -v
6.14.5

$ vue -V
@vue/cli 4.4.6

$ npm ls vue
vue@2.6.11 | MIT | deps: none | versions: 294

$ npm ls vue-infinite-loading
vue-infinite-loading@2.4.5 | MIT | deps: none | versions: 48

詳細

基本的に公式ドキュメントの通り。

セットアップ

参考: Installation

npm i でインインストール

1
$ npm i vue-infinite-loading

参考: Plugin API

プロジェクト全体で使うなら Vue.use で設定。

src/main.js

1
2
import InfiniteLoading from 'vue-infinite-loading';
Vue.use(InfiniteLoading, { /* options */ });

参考: Component

特定コンポーネントで使うなら components で設定。

xxxx.vue

1
2
3
4
5
6
7
8
9
<script>
import InfiniteLoading from 'vue-infinite-loading';

export default {
components: {
InfiniteLoading,
},
};
</script>

使い方

基本

参考: Start With Hacker News

<infinite-loading> タグを配置し、@infinite でスクロール時(下端付近までスクロールを検出時)のハンドラを設定。

以下は 100件まで item xx が追加されるシンプルな実装例。(公式ドキュメントは axios を使ってるが、わかりやすいように単純化)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<template>
<div>
<ul v-for="(item, i) in items" :key="i">
<li>{{ item }}</li>
</ul>
<infinite-loading @infinite="infiniteHandler" />
</div>
</template>

<script>
import InfiniteLoading from 'vue-infinite-loading';
export default {
components: {
InfiniteLoading,
},
data() {
return {
items: [],
};
},
methods: {
infiniteHandler($state) {
if (this.items.length === 100) {
$state.complete();
return;
}

this.items.push(`item ${this.items.length + 1}`);
$state.loaded();
},
},
};
</script>

無限スクロールをリセットしたい

参考: Use With Filter/Tabs

identifier プロパティを変更することで、別の無限スクロールとしてリセットさせることができる。

↓は細かい箇所は省略、実際には「検索ワードの変更(再検索)」「タブの切り替え」などのイベントに合わせて identifier (に bind しているデータ)を変更する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div>
<!-- 略 -->
<infinite-loading @infinite="infiniteHandler" :identifier="infiniteId" />
</div>
</template>

<script>
export default {
data() {
return {
items: [],
infiniteId: 0,
};
},
methods: {
reserHandler() {
this.infiniteId ++;
},
},
};
</script>

下から上にスクロールさせたい

参考: Top Direction Scroll

direction プロパティに top を設定し、ハンドラ内で先頭にデータを追加するようにすれば OK

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<template>
<div>
<!-- 略 -->
<infinite-loading @infinite="infiniteHandler" direction="top" />
</div>
</template>

<script>
export default {
data() {
return {
items: [],
};
},
methods: {
infiniteHandler($state) {
if (this.items.length === 100) {
$state.complete();
return;
}

this.items.unshift(`item ${this.items.length + 1}`);
$state.loaded();
},
},
};
</script>

メッセージを変更したい

参考: Configure Load Messages

全件取得完了、追加読み込み中に表示されるメッセージを変更するには spinner, no-more, no-results を設定

1
2
3
4
5
<infinite-loading @infinite="infiniteHandler">
<div slot="spinner">読込中</div>
<div slot="no-more">全件取得しました</div>
<div slot="no-results">データがありません</div>
</infinite-loading>

参考: Configure Plugin Options

Plugin API で利用している場合は以下のように Vue.use 時点で設定することも可能っぽい (試してない)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Vue.use(InfiniteLoading, {
props: {
spinner: 'default',
/* other props need to configure */
},
system: {
throttleLimit: 50,
/* other settings need to configure */
},
slots: {
noMore: 'No more message', // you can pass a string value
error: InfiniteError, // you also can pass a Vue component as a slot
},
});

まとめ

  • npm i vue-infinite-loading でインストール
  • <infinite-loading @infinite="infiniteHandler" /> を記述
  • infinite イベントのハンドラ内でデータの追加や、読み込み完了などの処理を実施

その他・メモ

2020/08/08 時点で(4baed2bb07)の実装方法は scroll イベントでの検出っぽい。

性能面で気になるなら IntersectionObserver を使う方が良いかもしれない。
※vue-infinite-loading の性能を計測したわけではないので、そこまで気にしなくても良いかもしれない。

以下、参考になりそうなページ (中身はちゃんと見てない)。

参考文献

関連記事

この記事が参考になった方
ここここからチャージや購入してくれると嬉しいです(ブログ主へのプレゼントではなく、ご自身へのチャージ)
欲しいもの / Wish list