Vueで無限スクロールを実装する方法

無限スクロールは、アプリのユーザーがページをスクロールダウンするときに、より多くのコンテンツを表示するために使用できるテクニックです。ページネーションの必要性をなくし、アプリのユーザーは大量のデータセットをスクロールし続けることができます。

Vueアプリケーションの設定

このチュートリアルに従うには、Vue 3とJavaScriptの基本的な理解が必要です。AxiosでHTTPリクエストを処理する方法を知っている必要があります。

無限スクロールを実装する方法を学習するには、まずお好みのディレクトリで次のnpmコマンドを実行して、新しいVueアプリを作成します。

npm create vue

プロジェクトの設定中、Vueはアプリのプリセットを選択するように求めます。アプリに追加する必要がないため、すべての機能でいいえを選択します。

新しいアプリを作成したら、アプリのディレクトリに移動し、次のnpmコマンドを実行して必要なパッケージをインストールします。

npm install axios @iconify/vue @vueuse/core

npmコマンドは、axios(HTTPリクエスト用)、@iconify/vue(Vueでの簡単なアイコン統合用)、@vueuse/core(基本的なVueユーティリティを提供)の3つのパッケージをインストールします。

axios@iconify/vueを使用して、データを取得し、アプリケーションにアイコンを追加します。@vueuse/coreには、無限スクロールを実現するためのuseInfiniteScrollコンポーネントを含むVueユーティリティが含まれています。

JSONPlaceholder APIからダミーデータを取得する

無限スクロール機能を実装するには、データが必要です。これらのデータをハードコードすることも、JSONPlaceholderのような無料の偽のAPIソースからデータを取得することもできます。

JSONPlaceholderからこれらのデータを取得すると、ほとんどのWebアプリケーションがハードコードされたデータではなくデータベースからデータを取得するため、実際のシナリオを模倣できます。

VueアプリケーションのAPIからデータを取得するには、srcディレクトリに新しいフォルダーを作成し、apiという名前を付けます。そのフォルダーで、新しいJavaScriptファイルを作成し、次のコードを貼り付けます。

//getComments.jsimport axios from "axios";async function getComments(max, omit) {try {const comments = await axios.get(https://jsonplaceholder.typicode.com/comments?_limit=${max}&_start=${omit});return comments.data.map((comment) => comment.body);} catch (error) {console.error(error);}}export default getComments;

コードスニペットは、APIエンドポイント"https://jsonplaceholder.typicode.com/comments"からコメントを取得するための非同期関数で構成されています。その後、関数をエクスポートします。

さらに詳しく説明すると、コードスニペットはaxiosライブラリのインポートから始まります。次に、コードは2つの引数、maxomitを持つgetComments関数を定義します。

getComments関数は、URLへのGETリクエストを行うaxios.get()メソッドを格納しています。URLには、テンプレートリテラル(``)を使用して文字列内に挿入されるクエリパラメータmaxomitが含まれています。これにより、動的な値をURLに渡すことができます。

その後、関数はmap関数を使用してAPIエンドポイントから受信したコメントのbodyで構成される新しい配列を返します。

エラーが発生した場合は、コードスニペットはそれをコンソールに記録します。コードスニペットはこの関数をアプリケーションの他の部分にエクスポートします。

無限スクロールコンポーネントを作成する

ダミーデータを取得するためのロジックを処理したので、ダミーデータを表示し、無限スクロール機能を処理するための新しいコンポーネントを作成できます。

src/componentsディレクトリにInfiniteScroll.vueという新しいファイルを作成し、次のコードを追加します。

<!-- InfiniteScroll.vue -->
<script setup>
import { ref } from "vue";
import getComments from "../api/getComments";
import { useInfiniteScroll } from "@vueuse/core";
const listEl = ref(null);
const commentsDisplayed = 20;
const commentsList = ref(await getComments(commentsDisplayed, 0));
const commentsToDisplayOnScroll = async () => {
const newComments = await getComments(
commentsDisplayed,
commentsList.value.length
);
commentsList.value.push(...newComments);
};
useInfiniteScroll(
listEl,
async () => {
await commentsToDisplayOnScroll();
},
{ distance: 10 }
);
</script>

上記のコードスニペットは、InfiniteScrollコンポーネントのスクリプトブロックを記述しています。

コードスニペットは、vue@vueuse/coreからそれぞれrefuseInfiniteScroll関数をインポートします。スニペットは、getComments.jsファイルからgetComments関数もインポートします。

次に、スニペットはref関数を使用してlistEl参照を作成します。listElは、無限スクロール機能を持つDOM要素を参照します。

commentsDisplayed変数は、ページに最初に表示するコメントの数を表します。commentsListには、コードスニペットがgetComments関数で取得したコメントの配列が格納されます。

スニペットは、getComments関数で新しいコメントを取得し、スプレッド演算子(...)を使用して既存のcommentsList配列に追加するcommentsToDisplayOnScroll非同期関数を定義します。

最後に、コードスニペットは、3つの引数を受け取るuseInfiniteScroll関数を呼び出して、無限スクロールの動作を有効にします。

  • DOM要素(listEl)参照は、アプリユーザーがスクロールするリストを表します。
  • ユーザーがスクロールして、新しいコメントを取得してcommentsListに追加するトリガーとなる非同期関数呼び出し。
  • プロパティを持つオプションの構成オブジェクト。オブジェクト{ distance: 10 }は、ユーザーがリストの底から10ピクセル離れたときに、新しいコメントの読み込みを開始することを指定します。

無限スクロールコンポーネントを使用する

InfiniteScrollコンポーネントのスクリプトブロックで無限スクロールのロジックを処理したら、テンプレートブロックでコンテンツをレンダリングする必要があります。

InfiniteScrollコンポーネントに次のコードブロックを貼り付けます。

<!-- InfiniteScroll.vue -->
<template>
<div>
<ul ref="listEl">
<li v-for="comment in commentsList">
{{ comment }}
</li>
</ul>
</div>
</template>

このコードブロックは、コメントのリストをレンダリングするVueコンポーネントのテンプレートを定義します。

    要素は、v-forディレクティブ(リストをレンダリングするため)で生成された
  • 要素のコレクションを保持し、commentsList配列を反復処理します。

    配列の各コメントは、データ補間({{ comment }})を使用して

  • 要素内に表示されます。コードブロックはlistEl参照を
      に割り当てて、無限スクロール機能を有効にします。

      次に、App.vueファイルでInfiniteScrollコンポーネントを使用できます。

      <!-- App.vue -->
      <script setup>
      import InfiniteScroll from "./components/InfiniteScroll.vue";
      import { Icon } from "@iconify/vue";
      </script>
      <template>
      <Suspense>
      <InfiniteScroll />
      <template #fallback>
      <Icon icon="eos-icons:bubble-loading" width="250" height="250" />
      </template>
      </Suspense>
      </template>
      

      上記のコードブロックは、InfiniteScrollコンポーネントとIconコンポーネントをインポートします。次に、InfiniteScrollコンポーネントをSuspenseコンポーネントでラップします。

      Suspenseコンポーネントを使用すると、VueがInfiniteScrollコンポーネントのすべての非同期関数を解決する間、フォールバックコンテンツ(アイコン)をレンダリングできます。

      これで、アプリのディレクトリでnpm run devコマンドを実行して、アプリケーションをプレビューできます。以下の画像と同様のインターフェイスが表示されるはずです。

      上記のプレビューには、commentsToBeDisplayed変数を10に設定したため、10件のコメントが表示されます。下にスクロールすると、アプリはさらに多くのコメントを読み込みます。

      無限スクロールのテクニックは、特にXやTiktokなどのソーシャルメディアアプリで、Webアプリケーションの間で人気があります。

      このテクニックにより、アプリユーザーは継続的により多くのデータを取得し、読む、学ぶ、見るためのコンテンツの常に拡大するストリームが提供されるため、関心を維持することができます。

      スロットを使用してVueコンポーネントを再利用する方法を学ぶ

      VueUseで利用可能なuseInfiniteScrollコンポーネントを使用して、無限スクロールのテクニックを実装する方法を学びました。

      最新のWebサイトでは、同じコンポーネントを異なるHTMLコンテンツでレンダリングすることが一般的です。Webアプリのさまざまな部分でこの一貫した雰囲気を実現するために、Vueコンポーネントを再利用する方法を学ぶことができます。