使用 vue-virtual-scroller 在 Vue.js 中执行列表和表格

作为开发人员,您可能不得不为应用程序实现一个大列表或表,要么通过加载大量数据而无需页面化,要么使用 无限滚动页面化并通过它滚动几次。

vue-virtual-scroller是一个Vue.js插件,它应用了virtual scroll技术,以便在DOM中有效地渲染列表,无论是简单的HTML ul > li列表,表或自定义列表。

设置视觉-虚拟扫描器

一旦您创建了一个基本的 Vue.js 项目,请从 npm 开始安装插件:

1$ npm install -D vue-virtual-scroller

然后,在你的 main.js 文件中,你必须包括它的 CSS 文件并初始化它:

1[label main.js]
2import "vue-virtual-scroller/dist/vue-virtual-scroller.css";
3import Vue from "vue";
4import VueVirtualScroller from "vue-virtual-scroller";
5
6Vue.use(VueVirtualScroller);
7// ...

这就足以开始使用它。

创建一个虚拟列表

要从一个简单的例子开始,让我们创建一个简单的列表,它需要大量的数据,并使用视觉扫描器来渲染它。

让我们使用 JSON-Generator来生成 5000 个条目的 JSON,然后将其保存到 data.json 文件中。

1[
2  '{{repeat(5000)}}',
3  {
4    _id: '{{objectId()}}',
5    age: '{{integer(20, 40)}}',
6    name: '{{firstName()}} {{surname()}}',
7    company: '{{company().toUpperCase()}}'
8  }
9]

让我们创建一个 VirtualList.vue 文件,在那里我们导入 data.json 并将其添加到一个项目组件状态属性。

 1[label VirtualList.vue]
 2<template>
 3  <virtual-scroller :items="items" item-height="40" content-tag="ul">
 4    <template slot-scope="props">
 5      <li :key="props.itemKey">{{props.item.name}}</li>
 6    </template>
 7  </virtual-scroller>
 8</template>
 9
10<script>
11import items from "./data.json";
12
13export default {
14  data: () => ({ items })
15};
16</script>

或者,由于我们正在创建一个列表,我们已经设置了content-tag="ul``,将内容包装成一个

    `标签。

    vue-virtual-scroller 允许使用 scoped slots来渲染内容,以实现完全灵活的渲染。

    props包含一个itemKey属性,我们应该使用:key="props.itemKey在内容的根上进行绑定,以便出于性能原因,然后我们可以访问包含原始项目的props.item从我们通过items属性的JSON到virtual-scroller

    如果您想对列表中的元素进行格式化,则可以将属性添加到虚拟扫描器组件中,并访问其内容:

    1<template>
    2  <virtual-scroller class="virtual-list" ...></virtual-scroller>
    3</template>
    4
    5<style>
    6.virtual-list ul {
    7  list-style: none;
    8}
    9</style>
    

    或者,对于范围式样式,请使用 /deep/ 选择器:

    1<style scoped>
    2.virtual-list /deep/ ul {
    3  list-style: none;
    4}
    5</style>
    

    创建一个虚拟图

    与 VirtualList 组件类似,让我们为表创建一个 VirtualTable.vue 文件:

     1[label VirtualTable.vue]
     2<template>
     3  <virtual-scroller :items="items" item-height="40" content-tag="table">
     4    <template slot-scope="props">
     5      <tr :key="props.itemKey">
     6        <td>{{props.item.age}}</td>
     7        <td>{{props.item.name}}</td>
     8        <td>{{props.item.company}}</td>
     9      </tr>
    10    </template>
    11  </virtual-scroller>
    12</template>
    13
    14<script>
    15import items from "./data.json";
    16
    17export default {
    18  data: () => ({ items })
    19};
    20</script>
    

    我们在这个示例中遇到一个问题:我们要将一个<thead>标签添加到表标题中,以显示列名称:年龄、姓名和公司。

    幸运的是,虚拟扫描器使用以下插槽结构来分发其内部内容:

     1<main>
     2  <slot name="before-container"></slot>
     3  <container>
     4    <slot name="before-content"></slot>
     5    <content>
     6      <!-- Your items here -->
     7    </content>
     8    <slot name="after-content"></slot>
     9  </container>
    10  <slot name="after-container"></slot>
    11</main>
    

    这些插槽中的任何一个都可以用来将内容放入其中。‘容器’将被‘容器标签’属性的标签值取代,默认情况下‘div’,而‘内容’将被‘内容标签’值取代。

    因此,很容易使用内容前插槽添加一个thead:

     1<template>
     2  <virtual-scroller
     3    :items="items"
     4    item-height="40"
     5    container-tag="table"
     6    content-tag="tbody"
     7    >
     8      <thead slot="before-content">
     9        <tr>
    10          <td>Age</td>
    11          <td>Name</td>
    12          <td>Company</td>
    13        </tr>
    14      </thead>
    15      <template slot-scope="props">
    16        <tr :key="props.itemKey">
    17          <td>{{props.item.age}}</td>
    18          <td>{{props.item.name}}</td>
    19          <td>{{props.item.company}}</td>
    20        </tr>
    21      </template>
    22  </virtual-scroller>
    23</template>
    

    请注意,我们已将content-tag="table``更改为container-tag="table``和content-tag="tbody以保持通常的表结构,因为现在我们正在使用更多元素。

    我相信你也可以想象如何添加一个tfoot元素 😉。

    包装上

    我们使用 vue-virtual-scroller 插件创建了 VirtualList 和 VirtualTable 的组件. 如果您尝试使用我们生成的 5000 个项目,它们应该非常顺利地渲染和滚动。

    您可以在 此 Codesandox中看到文章的工作代码。

    保持冷静

Published At
Categories with 技术
Tagged with
comments powered by Disqus