vue 虛擬列表滾動


需求來了

項目中有一個移動端的長列表,考慮再三,決定用虛擬列表優化一下,關於虛擬列表的實現網上有挺多方案的,為了省時省力還是決定采用成熟的第三方庫,於是開始 github 之旅~
搜索關鍵字 vue virtual ,選取前兩個 star hin 高的項目,展開看看對比對比看看哪個符合我的要求~是我的 the one~

對比之 vue-virtual-scroller

地址

[https://github.com/Akryum/vue-virtual-scroller] star: 6.2k

demo 地址

用法

  <RecycleScroller
    class="scroller"
    :items="list"
    :item-size="32"
    key-field="id"
    v-slot="{ item }"
  >
    <div class="user">
      {{ item.name }}
    </div>
  </RecycleScroller>

注意事項:

  • 官網的 demo 只提供了一次性加載大量數據的案例,並且親測,如果自己定義無限加載的方法話,向上滾動會出現白屏。

對比之 vue-virtual-scroll-list

地址

[https://github.com/tangbc/vue-virtual-scroll-list] star: 3.1k

demo 地址

[https://tangbc.github.io/vue-virtual-scroll-list/#/]

用法

<virtual-list style="height: 360px; overflow-y: auto;" // make list scrollable
      :data-key="'uid'"
      :data-sources="items"
      :data-component="itemComponent"
    />

注意事項

  • 列表項需要以組件的方式傳入
  • 如果需要用原生頁面的滾動事件,比如列表+上方固定欄的布局,可以開啟 :page-mode="true",取消 scroller 的樣式,原生。

對比結果:

經過對比最終決定使用 vue-virtual-scroll-list ,因為它在官方的 demo 中給出了無限加載的例子,且實測運行良好。而vue-virtual-scroller 則更適合用於前端分頁加載大量數據的例子。

使用方式:

下面是基於 vue3 composition api 進行的封裝,方便復用,如果是 vue2 的項目, 安裝 @vue/composition-api 插件就可以毫無阻礙的使用 composition-api 啦!親測沒問題。

  • 安裝 npm i vue-virtual-scroll-list --save

  • main.ts 全局注冊組件

// 全局注冊 虛擬滾動的組件
import VirtualList from 'vue-virtual-scroll-list'
Vue.component('virtual-list', VirtualList)
  • 封裝公共邏輯 useVirtualInfinite.ts
import { ref, onMounted, Ref } from 'vue'

declare type returnType = {
  loading: Ref<boolean>
  onScrollToBottom: () => void
  list: Ref<any[]>
}
export default function useVirtualInfinite (getListFn: ()=>Promise<any>) : returnType {
  const loading = ref(false)
  const list = ref<any[]>([])
  const onScrollToBottom = () => {
    getData()
  }

  // 獲取數據方法
  const getData = async () => {
    if (!loading.value) {
      loading.value = true
      const { data } = await getListFn()
      // eslint-disable-next-line
      data.rows.forEach((item: any) => (item.id = new Date().getTime()));
      list.value.push(...data.rows)
      loading.value = false
    }
  }

  // 掛載之后 獲取 data
  onMounted(() => {
    getData()
  })

  return {
    onScrollToBottom,
    loading,
    list
  }
}
  • 愉快使用
<template>
  <virtual-list
    :data-key="'id'"
    :data-sources="list"
    :data-component="commentItem"
    :page-mode="true"
    v-on:tobottom="onScrollToBottom"
  >
    <div slot="footer" class="loading-spinner text-center">加載中...</div>
  </virtual-list>
</template>

<script>
const { list, onScrollToBottom } = useVirtualInfinite(getList)
return {
    list,
    onScrollToBottom
}
</script>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM