Vue使用三方工具vueUse實現(xiàn)虛擬列表
前言
書接上文,前篇文章介紹了如何手寫一個虛擬列表,這篇文章就介紹一下如何偷懶使用現(xiàn)有的三方工具實現(xiàn)
傳送門:如果讓你渲染十萬條數(shù)據(jù),無腦全部渲染?拖出去斬了
vueUse方案實現(xiàn)
采用vueUse
中的useVirtualList
方法同樣可以實現(xiàn)虛擬列表(相當(dāng)于是使用一個封裝好的方法)
步驟:
1.裝包
npm i @vueuse/core
2.導(dǎo)入useVirtualList
方法
如何使用?
在使用useVirtualList
方法時需要傳入兩個參數(shù),一個是數(shù)據(jù)源(就是你那十萬條數(shù)據(jù)),一個是配置項(配置每項的高度)
在配置項中配置的高度一定要和模板中渲染的每一項的高度相同(即配置項的高度要與css
中的高度保持一致)
這個方法返回三個字段,一個處理后的數(shù)據(jù)源,兩個依賴項,這兩個依賴項需要綁定到視圖區(qū)域和占位盒子身上,從而實現(xiàn)虛擬列表的效果
手動添加類名,然后審查元素:
<template> <div v-bind="containerProps" style="height: 500px" class="container"> <div v-bind="wrapperProps" class="slot"> <div v-for="item in list" :key="item.data.id" style="height: 40px"> Row: {{ item.data }} </div> </div> </div> </template>
大致的效果就是虛擬列表的div
包裹著占位的div
,占位的div
內(nèi)進(jìn)行渲染。當(dāng)然,樣式自己就根據(jù)需要添加即可
完整代碼
<script setup lang="ts"> import { useVirtualList } from '@vueuse/core' import { onMounted, ref } from 'vue' type Item = { id: number name: string } // 所有的數(shù)據(jù),比如這個數(shù)組存放了十萬條數(shù)據(jù) const allListData = ref<Item[]>([]) // 獲取十萬條數(shù)據(jù) const getData = () => { for (let i = 0; i < 10000; i++) { allListData.value.push({ name: `第${i}條數(shù)據(jù)`, id: i }) } } onMounted(() => { getData() }) const { list, containerProps, wrapperProps } = useVirtualList(allListData, { // 此處配置的高度一定要和31行渲染時每一行的高度相同 itemHeight: 40 }) </script> <template> <div v-bind="containerProps" style="height: 500px" class="container"> <div v-bind="wrapperProps" class="slot"> <div v-for="item in list" :key="item.data.id" style="height: 40px"> Row: {{ item.data }} </div> </div> </div> </template> <style scoped lang="scss"> .container { border: 1px solid black; } </style>
同時注意,將原始數(shù)據(jù)源傳給useVirtualList
之后返回的list
是經(jīng)過封裝過的,想這里原本數(shù)據(jù)的每一項的結(jié)構(gòu)是{ name:'', id:xx }
,經(jīng)過處理后,再想訪問name
或者id
,就得多訪問一層data
,即list.data.name / list.data.id
完整代碼
<script setup lang="ts"> import { onMounted, ref } from 'vue' import { RecycleScroller } from 'vue-virtual-scroller' import 'vue-virtual-scroller/dist/vue-virtual-scroller.css' type Item = { id: number name: string } // 所有的數(shù)據(jù),比如這個數(shù)組存放了十萬條數(shù)據(jù) const allListData = ref<Item[]>([]) // 獲取十萬條數(shù)據(jù) const getData = () => { for (let i = 0; i < 10000; i++) { allListData.value.push({ name: `第${i}條數(shù)據(jù)`, id: i }) } } onMounted(() => { getData() }) // 每一項的高度,比如 40 像素 const itemHeight = ref(40) </script> <template> <RecycleScroller class="viewport" :items="allListData" :item-size="itemHeight" key-field="id" v-slot="{ item }" item-class="item" > {{ item.name }} </RecycleScroller> </template> <style scoped lang="scss"> .viewport { box-sizing: border-box; width: 240px; height: 400px; border: solid 1px #000000; // 開啟滾動條 overflow-y: auto; <!-- 由于模板中使用了 item-class 屬性將渲染的每一項的類名改為 item,所以這里開啟深層次的樣式修改--> :deep(.item) { box-sizing: border-box; width: 100%; height: 40px; // 高度設(shè)置得和 item-size 屬性的值一致。表示每一項的高度 display: flex; justify-content: center; align-items: center; // 隔行變色 &:nth-child(even) { background: skyblue; } &:nth-child(odd) { background: red; } } } </style>
實現(xiàn)效果
審查一下元素:
其實可以發(fā)現(xiàn)底層實現(xiàn)原理和之前手寫的部分差不多,都是最外層一個虛擬列表盒子,內(nèi)層放置一個具有所有數(shù)據(jù)的高度的盒子,然后再設(shè)置一個視圖層進(jìn)行滾動。但是使用封裝好的東西可以不用自己設(shè)置定位以及更新top
值,而且其實它的文檔里還有其他很多的屬性和事件,拓展性強。還支持每一項的高度可以不同(可能在那種評論區(qū)用得多,畢竟每條評論的內(nèi)容不一定都相同)
報錯問題
由于使用的是 Vue3 + TS,所以在導(dǎo)入的時候會有類型報錯,雖然不影響功能
嘗試下載提示中的包文件,但是竟然顯示找不到了,可能是在@types
中沒有這個包的聲明文件吧
到此這篇關(guān)于Vue使用三方工具vueUse實現(xiàn)虛擬列表的文章就介紹到這了,更多相關(guān)Vue vueUse虛擬列表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Vue+ElementUI動態(tài)生成面包屑導(dǎo)航教程
Vue和ElementUI都是非常流行的前端開發(fā)框架,它們可以讓我們更加便捷地開發(fā)前端應(yīng)用,下面這篇文章主要給大家介紹了關(guān)于使用Vue+ElementUI動態(tài)生成面包屑導(dǎo)航的相關(guān)資料,需要的朋友可以參考下2023-05-05