Thứ hai, 09/04/2018 | 00:00 GMT+7

Danh sách và bảng biểu diễn trong Vue.js với vue-virtual-scroller


Là một nhà phát triển, có thể bạn đã phải triển khai một danh sách hoặc bảng lớn cho một ứng dụng, bằng cách tải nhiều dữ liệu mà không phân trang hoặc sử dụng phân trang cuộn vô hạn và cuộn nhiều lần qua nó. Các danh sách hoặc bảng này có thể trở nên chậm chạp, đặc biệt khi chúng có nhiều phần tử, kiểu CSS và / hoặc quá trình chuyển đổi.

vue-virtual-scroller là một plugin Vue.js áp dụng kỹ thuật cuộn ảo để hiển thị một cách hiệu quả một danh sách cho DOM, cho dù đó là danh sách ul > li HTML thuần túy, một bảng hay một danh sách tùy chỉnh.

Cài đặt vue-virtual-scroller

Sau khi bạn đã tạo dự án Vue.js cơ bản, hãy bắt đầu bằng cách cài đặt plugin từ npm:

$ npm install -D vue-virtual-scroller

Sau đó, trong file main.js của bạn, bạn phải bao gồm file CSS của nó và khởi tạo nó:

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

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

Đó là đủ để bắt đầu sử dụng nó.

Tạo danh sách ảo

Để bắt đầu với một ví dụ đơn giản, hãy tạo một danh sách đơn giản có nhiều dữ liệu và sử dụng vue-virtual-scroller để hiển thị nó.

Hãy sử dụng JSON-Generator để tạo JSON cho 5000 mục nhập và lưu nó vào file data.json . Bạn có thể sử dụng cấu trúc sau:

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

Hãy tạo một file VirtualList.vue , nơi ta nhập data.json và thêm nó vào thuộc tính trạng thái thành phần items . Sau đó, sử dụng thành phần <virtual-scroller> , chuyển các mục đó:

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>

Ta phải đặt item-height cho thành phần cuộn ảo. Ngoài ra, vì ta đang tạo một danh sách, ta đã đặt content-tag="ul" sẽ bọc nội dung thành một <ul> .

vue-virtual-scroller cho phép sử dụng các khe có phạm vi để hiển thị nội dung nhằm hoàn toàn linh hoạt với việc kết xuất. Bằng cách sử dụng slot-scope="props" ta có quyền truy cập vào dữ liệu tiếp xúc với cuộn ảo và sử dụng nó để hiển thị.

props chứa itemKey tính itemKey mà ta nên ràng buộc bằng cách sử dụng :key="props.itemKey" trên folder root của nội dung vì lý do hiệu suất. Sau đó, ta có thể truy cập props.item chứa mục thô từ JSON mà ta đã chuyển qua thuộc tính items đến virtual-scroller .

Nếu bạn muốn tạo kiểu cho các phần tử trong danh sách, bạn có thể thêm thuộc tính class vào thành phần virtual-scroller và truy cập nội dung của nó:

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

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

Hoặc, với các kiểu phạm vi, hãy sử dụng /deep/ selector:

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

Tạo VirtualTable

Tương tự với thành phần VirtualList , hãy tạo file VirtualTable.vue cho một bảng:

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>

Ta gặp phải một vấn đề với ví dụ này; ta muốn thêm <thead> làm tiêu đề bảng để hiển thị tên các cột: Tuổi , TênCông ty .

May mắn là virtual-scroller phân phối nội dung bên trong của nó bằng cách sử dụng cấu trúc vị trí sau:

<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>

Bất kỳ vị trí nào trong số đó đều được dùng để đặt nội dung vào đó. container sẽ được thay thế bằng giá trị thẻ của thuộc container-tag vùng container-tag , theo div mặc định và content bằng giá trị content-tag .

Đó là do đó dễ dàng để thêm một thead sử dụng before-content khe:

<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>

Lưu ý ta đã thay đổi content-tag="table" cho container-tag="table"content-tag="tbody" để giữ cấu trúc bảng thông thường, vì bây giờ ta đang sử dụng nhiều phần tử hơn.

Tôi chắc rằng bạn cũng có thể hình dung cách thêm phần tử tfoot 😉.

Kết thúc

Ta đã sử dụng plugin vue-virtual-scroller để tạo các thành phần cho VirtualListVirtualTable . Nếu bạn dùng thử chúng với 5000 mục ta đã tạo, chúng sẽ hiển thị và cuộn khá trơn tru. Kiểm tra tài liệu vue-virtual-scroller để xem thêm các tùy chọn và tùy chỉnh.

Bạn có thể xem mã làm việc của bài viết trong Codesandox này .

Giữ bình tĩnh 🦄


Tags:

Các tin liên quan