コラム

[Vue.js]Vue3対応無限スクロールプラグインのv3-infinite-loading使用例

今回はVue3対応の無限スクロールプラグインのv3-infinite-loadingの使用方法を説明していきたいと思います。
無限スクロールプラグインの比較は無限スクロールプラグイン比較 をご覧下さい。

環境

Vue 3
v3-infinite-loading 1.0.6

Vue.jsプロジェクト作成

次のコマンドを実行

vue create [プロジェクト名]

今回はスクローラーを試すだけなのでDefault (Vue 3) ([Vue 3] babel, eslint)を選択

? Please pick a preset:
  router-sample ([Vue 2] babel, router, eslint)
  aa ([Vue 3] babel, eslint)
  Default ([Vue 2] babel, eslint)
> Default (Vue 3) ([Vue 3] babel, eslint)
  Manually select features

プロジェクトが作成したら、[プロジェクト名]のディレクトリに移動してインストールコマンド実行

 npm install v3-infinite-loading --save

実装

画面のイメージ

ディレクトリ構成

プロジェクト名/
           ├─ src/
                ├─ App.vue ←メインロジックを記述
                ├─ main.js ←変更なし     

App.vue

<template>
  <div id="app">
    <center>
    <div style="width:250px;border:solid 1px;">
      <div style="display: flex;border-bottom:solid 1px;background:lightgray">
        <div style="width:100px;border-right:solid 1px;">ID</div>
        <div style="width:100px;">タイトル</div>
      </div>
    </div>
    <div id="box" style="width:250px;height: 360px; overflow-y: scroll;">
      ①
      <div style="display: flex;border-bottom:solid 1px;" v-for="item in reacData.items" :key="item.id">
        <div ref="id" style="width:100px;border-right:solid 1px;">{{ item.id }}</div>
        <div ref="text" style="width:100px;">{{ item.text }}</div>
      </div>
      <InfiniteLoading  @infinite="load" target="#box"> ②
        <template #complete>
        <span>読み込み終了</span>
        </template>
      </InfiniteLoading>
    </div>

    </center>
  </div>
</template>

<script>
import { reactive, ref  } from "vue"; ③
import InfiniteLoading from "v3-infinite-loading"; ④

export default ({ ⑤
  name: 'App',
  components: { ⑥
    InfiniteLoading,
  },

  setup() {

    const reacData = reactive({ ⑦
      items: []
    });
   
    //Refs使用用に定義する ⑧
    const id = ref(null)
   const text = ref(null)
  
    let itemCounter = 1;
  
    //スクローラーからコールされるデータ取得メソッド
    const load =  async($state) => { ⑨
      try {
       if( itemCounter >= 2000){
          $state.complete()
        }else{
          var data = []
          for(let i = itemCounter;i<=itemCounter + 30;  i++ ){
            data.push({
              id: i,
              text: 'テキスト'+ i,
            });
          }
          itemCounter += 30
          reacData.items = reacData.items.concat( data )
          $state.loaded()
      
        }
      } catch (error) {
        console.log("error");
        $state.error();
      }
     };
   
     //templateで使用するメソッド、変数をreturnで返す  
     return { ⑩
        reacData,
        load,
        id,
        text
     };
   }
});
</script>

<style>
  省略
</style>

① 「setup」で定義し、「return」で返しているリアクティブデータの「items」をテーブルにリスト表示します。
② 無限スクローラを定義しています。設定するパラメーターは以下。

項目説明
@infiniteデータ取得用メソッドを設定します。
スクロール時に任意のタイミングで呼ばれます。
targetスクロール対象のHTML要素のIDを設定します。

他にも設定可能な項目はあります。詳細はこちらのサイトにあります。

③ Vueモジュールから必要な機能をインポートします。今回は「reactive」と「ref」を使用します。
④ 「v3-infinite-loading」のモジュールをインポートします。
⑤ 通常と同様に「export default」して、その中にモジュールの実装をしています。TypeScriptを使用する場合はVueから「defineComponent」インポートして「export default defineComponent」の中に実装する必要があります。
⑥ インポートした「v3-infinite-loading」モジュールをコンポーネントとして設定します。
⑦ composition-apiを使用しているので、外で使用する変数は「reactive」か「ref」で宣言します、今回テーブルに表示するデータは「items」という変数名で「reactive」として宣言します。
⑧ refsを使用する為の変数を定義しています。「id」と「text」を「ref」として宣言します。
⑨ データを取得するメソッドを実装しています。メソッドは非同期メソッドとして宣言します。
⑩ templateで使用する変数、メソッドを「return」で部分に記述します。

Refsの使用

composition-apiでのrefsの使用方法は以下の手順で行います。

① template上の要素にref属性を追記します。例: <div ref="id"
② setupで設定したrefに該当する変数を宣言します。例:const id = ref(null)
③ setupの「return」に宣言した変数を記述します。
④ 宣言した変数を使用すればrefsで設定した要素にアクセスする事が可能です。

//最上位のID属性の背景色を赤にする例 
id.value[0].style.background="red"

//2番目のID属性の背景色を赤にする例 
id.value[1].style.background="red"

最後に

以上、v3-infinite-loadingの使用方法の説明でした。
このプラグインは、Vue3に対応しているというのが魅力ですが、リストのDOM要素はデータが追加して行くと増えていくので、大量データを扱う時には注意が必要です。特にスマフォのページを作成する場合など。
他のプラグインとの比較は無限スクロールプラグイン比較 で行っているので興味のある方は見てみて下さい。

この記事をシェアする
  • Facebookアイコン
  • Twitterアイコン
  • LINEアイコン

お問い合わせ ITに関するお悩み不安が少しでもありましたら、
ぜひお気軽にお問い合わせください

お客様のお悩みや不安、課題などを丁寧に、そして誠実にお伺いいたします。

お問い合わせはこちら
お電話でのお問い合わせ 03-5820-1777(平日10:00〜18:00)
よくあるご質問