一個支援百萬量級的vue3無限滾動元件

TNTWEB發表於2022-03-28

什麼是無限滾動元件

當我們的列表頁有幾百萬條資料的時候應該怎麼辦呢?分頁也許不是最好的體驗方式,無限滾動就是解決這種場景更好的技術手段。當使用者向下滾動內容時,會自動新增下一頁的list元件,載入更多內容。使用者無需等待頁面預載入,而且對於前端渲染來說不會反覆渲染大量元件提高了頁面渲染效能。所以無限滾動可以為使用者提供更好的體驗。

a.png

無限滾動是電商網站、CMS後臺等應用程式中非常常見的一種模式。線上零售商喜歡這種載入產品的模式,因為它允許使用者無縫瀏覽一個類別中可用的每個產品,而不必經常暫停並等待下一頁載入。

關於vue3-infinite-list

官網: https://github.com/tnfe/vue3-...

vue3-infinite-list是一個針對vue3的短小精悍的無限滾動元件,它體積非常小、零依賴gzip只有 3kb。雖然vue相關的無限滾動開源元件也有很多,但是對比同類產品vue3-infinite-list依然有不少自己的特點,並且它完全使用vue3 setup api + typescript編寫,專案LOGO是一隻千足毛毛蟲? 。

logo-big.png

特性

  • 體積小 & 零依賴 – gzipped 後只有 3kb
  • 支援百萬級列表渲染, 不費吹灰之力
  • 支援滾動到指定條目 和 指定初始滾動偏移量
  • 支援固定 和 可變 寬/高的各類列表
  • 支援垂直 or 水平 不同佈局的列表
  • For Vue3 typescript編寫
  • 使用簡單可以結合各類UI庫使用

1.jpg

如何使用

demo6.gif

使用 npm:

npm install vue3-infinite-list --save

使用 yarn:

yarn add vue3-infinite-list

引用

import InfiniteList from 'vue3-infinite-list';
  <InfiniteList 
   :data="data" 
   :width="'100%'" 
   :height="500" 
   :itemSize="50" 
   :debug="debug" 
   v-slot="{ item, index }"
   >
    <div class="li-con">{{ index + 1 }} : {{ item }}</div>
  </InfiniteList>

使用示例

  1. 基本用法: item固定高度型別, 垂直滾動(預設) demo

demo1.gif

使用非常簡單,內部可以結合element-plus或者antd-vue、tdesign等UI庫。

<InfiniteList 
  :data="data" 
  :width="'100%'" 
  :height="500" 
  :itemSize="50" 
  :debug="debug" 
  v-slot="{ item, index }"
>
  <div class="li-con">{{ index + 1 }} : {{ item }}</div>
</InfiniteList>
  1. 設定滾動方向為水平方向 demo

      <InfiniteList
     :data="data"
     :width="900"
     :height="220"
     :itemSize="115"
     scrollDirection="horizontal"
     :debug="debug"
     v-slot="{ item, index }"
      >
     <div class="li-con li-con-r">
       item{{ index }} <br />
       xxxxxxx <br />
       xxxxxxx <br />
       <el-button type="primary" round>Primary</el-button>
     </div>
      </InfiniteList>

    這裡scrollDirection="horizontal"可以設定滾動方向為水平。

  2. 動態控制滾動高度(每一項item高度值是變化的) demo

demo3.gif

  <InfiniteList
    :data="data"
    :width="'100%'"
    :height="520"
    :itemSize="getItemSize"
    :debug="debug"
    v-slot="{ item, index }"
  >
    <div class="li-con">item {{ index }} : {{ item }}</div>
  </InfiniteList>
// 通過這個函式可以動態設定元素寬高.
const getItemSize = (i: number): number => {
      switch (i % 4) {
        case 1:
          return 80;
        case 2:
          return 50;
        case 3:
          return 100;
        default:
          return 200;
      }
  };

這裡 getItemSize 是一個有如下語法的函式 : (i: number): number, 通過這個函式可以動態設定元素寬高。

  1. 滾動到指定元素位置 demo

      <InfiniteList
     :data="data"
     :width="'100%'"
     :height="500"
     :itemSize="getItemSize"
     :scrollToIndex="scrollToIndex"
     :debug="debug"
     v-slot="{ item, index }"
      >
     <div class="li-con" :class="getClass(index)">item{{ index + 1 }} : {{ item }}</div>
      </InfiniteList>

    你也可以使用 scrollToIndex 來滾動到指定元素。

  2. 滾動到指定元素 (更精細的對齊方式) demo

     <InfiniteList
       :data="data"
       :width="'100%'"
       :height="500"
       :itemSize="getItemSize"
       :scrollToIndex="scrollToIndex"
       :scrollToAlignment="scrollToAlignment"
       :debug="debug"
       v-slot="{ item, index }"
     >
       <div 
         class="li-con" 
         :class="getClass(index)"
        >
          item{{ index + 1 }} : {{ item }}
       </div>
     </InfiniteList>

    你可以使用 scrollToIndex 和 scrollToAlignment 屬性來指定滾動元素如何與滾動區域對齊, 由四個選項: autostartcenterend,分別對應自動對齊、位於容器起始,位於容器中間,位於容器末尾。

  3. 滾動到指定位置,單位是畫素 demo

  <InfiniteList
    :data="data"
    :width="'100%'"
    :height="500"
    :itemSize="90"
    :scrollOffset="scrollOffset"
    :debug="debug"
    v-slot="{ item, index }"
  >
    <el-row class="mb-4 li-con">
      <el-col :span="8">index: {{ index + 1 }} </el-col>
      <el-col :span="8">xxxxxxxxxx</el-col>
      <el-col :span="8">
        <el-button type="primary">Primary</el-button> 
        <el-button type="success">Success</el-button></el-col
      >
    </el-row>
  </InfiniteList>

你也可以使用 scrollOffset 來滾動到指定位置。

  1. 支援動態變更資料 demo

      <InfiniteList 
     :data="data" 
     :width="'100%'" 
     :height="500" 
     :itemSize="60" 
     :debug="debug" 
     v-slot="{ item, index }"
      >
     <el-row class="li-con">
       <el-col :span="6">item{{ index + 1 }}</el-col>
       <el-col :span="6">2022-05-01</el-col>
       <el-col :span="6">Name: Tom</el-col>
       <el-col :span="6">
         <el-button type="primary">Button</el-button>
         <el-button type="success">Button</el-button>
       </el-col>
     </el-row>
      </InfiniteList>

    只需要動態的改變繫結的 data.

  2. 設定額外渲染元素的數量 demo

<InfiniteList 
  :overscanCount="2" 
  :data="data" 
  :width="'100%'" 
  :height="500" 
  :itemSize="50" 
  :debug="debug" 
  v-slot="{ item, index }"
>
  <div class="li-con">{{ index + 1 }} : {{ item }}</div>
</InfiniteList>
在可見的item上/下再各多渲染額外的overscanCount個item。調整它可以幫助減少某些瀏覽器/裝置上的滾動閃爍。

2.png

元件的屬性和配置

屬性型別是否必須?描述
widthNumber or String*列表寬度. 在滾動方向是 'horizontal'是用於確定滾動元素個數.
heightNumber or String*列表寬度. 在滾動方向是 'vertical'是用於確定滾動元素個數.
dataany[]構建滾動元素的資料
itemSize(index: number): number 可以是一個固定的寬/高(取決於滾動方向), 一個包含列表所有元素的陣列, 或者是返回指定位置元素高度的函式: (index: number): number
scrollDirectionString 指定滾動方向 'vertical' (預設) 或 'horizontal'.
scrollOffsetNumber 可以指定滾動位置
scrollToIndexNumber 可以指定到滾動到哪個元素
scrollToAlignmentString 結合 scrollToIndex一起用, 用於控制滾動到的元素的對齊方式. 可選: 'start''center''end' or 'auto'. 使用 'start' 將對齊到容器的起始位置, 'end' 則對齊到元素的結尾. 使用 'center可以對齊到容器正中間. 'auto' 則是滾動到scrollToIndex指定元素恰好完全可見的位置
overscanCountNumber 在可見元素上/下額外渲染的元素數量. 這可以減少在特定瀏覽器/裝置上的閃爍
width 在 scrollDirection 是 'vertical'時只能是string型別。類似的, Height 在 scrollDirection 是 'horizontal'時也只能是string型別*

結尾

一款零依賴,適用於vue的短小精悍的無限滾動載入庫的使用方法就介紹完了,是不超級容易上手,趕緊使用起來吧,使用過程中有任何問題,請在此 report it 提報。

相關文章