開発者は、ページネーションなしで大量のデータを読み込むか、無限スクロールページネーションを使用して数回スクロールすることにより、アプリの大きなリストまたはテーブルを実装する必要がありました。 これらのリストやテーブルは、特に要素、CSSスタイル、トランジションがたくさんある場合、遅くなる可能性があります。

vue-virtual-scroller は、仮想スクロール手法を適用して、プレーンHTMLであるかどうかに関係なく、リストをDOMにパフォーマンス的にレンダリングするVue.jsプラグインです。 ul > li リスト、テーブル、またはカスタマイズされたリスト。

vue-virtual-scrollerをセットアップする

基本的なVue.jsプロジェクトを作成したら、npmからプラグインをインストールすることから始めます。

$ npm install -D vue-virtual-scroller

次に、 main.js ファイルにCSSファイルを含めて、初期化する必要があります。

main.js
import "vue-virtual-scroller/dist/vue-virtual-scroller.css";
import Vue from "vue";
import VueVirtualScroller from "vue-virtual-scroller";

Vue.use(VueVirtualScroller);
// ...

それはそれを使い始めるのに十分なはずです。

VirtualListの作成

簡単な例から始めて、大量のデータを取得し、vue-virtual-scrollerを使用してレンダリングするプレーンリストを作成しましょう。

JSON-Generator を使用して5000エントリのJSONを生成し、data.jsonファイルに保存してみましょう。 次の構造を使用できます。

[
  '{{repeat(5000)}}',
  {
    _id: '{{objectId()}}',
    age: '{{integer(20, 40)}}',
    name: '{{firstName()}} {{surname()}}',
    company: '{{company().toUpperCase()}}'
  }
]

VirtualList.vue ファイルを作成してみましょう。ここで、 data.json をインポートして、 items コンポーネント状態プロパティ。 次に、 <virtual-scroller> コンポーネント、それらのアイテムを渡す:

VirtualList.vue
<template>
  <virtual-scroller :items="items" item-height="40" content-tag="ul">
    <template slot-scope="props">
      <li :key="props.itemKey">{{props.item.name}}</li>
    </template>
  </virtual-scroller>
</template>

<script>
import items from "./data.json";

export default {
  data: () => ({ items })
};
</script>

設定する必要があります item-height 仮想スクローラーコンポーネントに。 または、リストを作成しているので、 content-tag="ul" 内容をにラップします <ul> 鬼ごっこ。

vue-virtual-scrollerを使用すると、スコープスロットを使用してコンテンツをレンダリングし、レンダリングの柔軟性を最大限に高めることができます。 を使用して slot-scope="props" 仮想スクローラーで公開されたデータにアクセスし、それをレンダリングに使用します。

props が含まれています itemKey を使用してバインドする必要があるプロパティ :key="props.itemKey" パフォーマンス上の理由から、コンテンツのルートにあります。 その後、アクセスできます props.item 通過したJSONからの生のアイテムが含まれています items プロパティに virtual-scroller.

リスト内の要素のスタイルを設定する場合は、 class に属性 virtual-scroller コンポーネント、およびそのコンテンツにアクセスします。

<template>
  <virtual-scroller class="virtual-list" ...></virtual-scroller>
</template>

<style>
.virtual-list ul {
  list-style: none;
}
</style>

または、スコープ付きスタイルでは、 /deep/ セレクタ:

<style scoped>
.virtual-list /deep/ ul {
  list-style: none;
}
</style>

VirtualTableの作成

VirtualList コンポーネントと同様に、テーブルのVirtualTable.vueファイルを作成しましょう。

VirtualTable.vue
<template>
  <virtual-scroller :items="items" item-height="40" content-tag="table">
    <template slot-scope="props">
      <tr :key="props.itemKey">
        <td>{{props.item.age}}</td>
        <td>{{props.item.name}}</td>
        <td>{{props.item.company}}</td>
      </tr>
    </template>
  </virtual-scroller>
</template>

<script>
import items from "./data.json";

export default {
  data: () => ({ items })
};
</script>

この例で問題が発生しました。 追加したい <thead> 列名を表示するために、テーブルヘッダーとしてタグを付けます: Age Name 、およびCompany

幸い、virtual-scrollerは、次のスロット構造を使用して内部コンテンツを配布します。

<main>
  <slot name="before-container"></slot>
  <container>
    <slot name="before-content"></slot>
    <content>
      <!-- Your items here -->
    </content>
    <slot name="after-content"></slot>
  </container>
  <slot name="after-container"></slot>
</main>

これらのスロットのいずれかを使用して、そこにコンテンツを配置できます。 container のタグ値に置き換えられます container-tag プロパティ、デフォルトでは div、 そしてその content によって content-tag 価値。

したがって、追加するのは簡単です thead を使用して before-content スロット:

<template>
  <virtual-scroller
    :items="items"
    item-height="40"
    container-tag="table"
    content-tag="tbody"
    >
      <thead slot="before-content">
        <tr>
          <td>Age</td>
          <td>Name</td>
          <td>Company</td>
        </tr>
      </thead>
      <template slot-scope="props">
        <tr :key="props.itemKey">
          <td>{{props.item.age}}</td>
          <td>{{props.item.name}}</td>
          <td>{{props.item.company}}</td>
        </tr>
      </template>
  </virtual-scroller>
</template>

変更したことに注意してください content-tag="table" 為に container-tag="table"content-tag="tbody" 通常のテーブル構造を維持するために、現在はより多くの要素を使用しています。

追加する方法を想像できると思います tfoot 要素も😉。

まとめ

vue-virtual-scrollerプラグインを使用して、VirtualListおよびVirtualTableのコンポーネントを作成しました。 生成した5000個のアイテムで試してみると、レンダリングとスクロールが非常にスムーズになります。 vue-virtual-scroller docs をチェックして、その他のオプションとカスタマイズを確認してください。

この記事の動作コードは、このCodesandoxで確認できます。

涼しくしてください🦄