vue長列表優(yōu)化之虛擬列表實現(xiàn)過程詳解
前言
應用場景:后臺一次性發(fā)送上千條或更多數(shù)據(jù)給前臺
場景模擬:用戶發(fā)起一個請求,后臺發(fā)送了10w條數(shù)據(jù)
使用虛擬列表之前:前臺需要生成10w個dom節(jié)點用來渲染頁面
使用虛擬列表之后:前臺只需要生成少量dom節(jié)點(dom節(jié)點數(shù)量取決于前端視圖需要展示的數(shù)量),就可以實現(xiàn)對這10w條數(shù)據(jù)的視圖渲染
總之:虛擬列表就是固定dom節(jié)點數(shù)量,通過修改dom節(jié)點的內(nèi)容而達到不重新增加(或刪除)dom節(jié)點來實現(xiàn)列表的更新
實現(xiàn)原理

- 監(jiān)聽頁面滾動,獲取滾動的高度scrolltop
- 根據(jù)scrolltop,可以知道當前應該展示哪一段數(shù)據(jù)(即獲取要展示數(shù)據(jù)的index)
- 根據(jù)當前展示的數(shù)據(jù)在長列表中的index,對列表進行偏移
實現(xiàn)思路是這樣的:
設置列表初始值
- 需要展示給用戶的數(shù)量showNum
- 列表item的高度itemHeight
- 需要展示的第一條數(shù)據(jù)的下標start
- 需要展示的最后一條數(shù)據(jù)的下標end
- 通過start和end已經(jīng)showNum,我們可以得到需要展示的列表項showList,我們可以通過vue的計算屬性來實時獲取新的showList
建立列表視圖模型
- 給列表視圖設置高度ListWrapHeight
- 根據(jù)itemHeight和showNum,我們可以得到列表總高度ListHeight,我們必須要使得ListHeight高度大于ListWrapHeight,這樣才能實現(xiàn)滾動
監(jiān)聽頁面滾動
- 給列表視圖模型設置監(jiān)聽函數(shù),每當列表視圖發(fā)生滾動,就執(zhí)行回調(diào),獲取滾動高度scrolltop
- 通過scrolltop和itemHeight我們可以得到新的start以及end,從而獲取到新的showList
- 通過start和itemHeight我們可以給list設置偏移(translate),從而達到讓start對應的數(shù)據(jù)展示在視圖模型的效果
注意:列表視圖模型和列表并不是一個東西,視圖模型表示者頁面供列表展示的一塊區(qū)域,而列表表示的是需要展示的列表項總高度
這是列表視圖模型

這是列表

列表中超出視圖模型的節(jié)點就被隱藏了
為什么限制了展示列表項的長度(限制了dom數(shù)量),視圖模型還能持續(xù)滾動?
給列表設置translate會增大列表的高度,既然list的高度變大了,那么視圖模型就可以繼續(xù)滾動
實現(xiàn)代碼
? 以vue3為例(不管是vue2或是vue3,實現(xiàn)虛擬列表的核心代碼都是相同的,即監(jiān)聽滾動,賦新值)
<div ref="listWrap" class="list-wrap" @scroll="scrollListener">
<div class="list" ref="List">
<slot v-for="item in showList" :songInfo="item" :key="item.id"></slot>
</div>
</div>
setup(props) {
const list = ref(props.list); //長列表數(shù)據(jù)
const itemHeight = ref(props.itemHeight); //item高度
const showNum = ref(props.showNum); //展示的數(shù)據(jù)
const start = ref(props.start); //滾動過程中的開始索引
const end = ref(props.end); //滾動過程中的結束索引
const listWrap = ref(null); //獲取列表視圖模型節(jié)點
const List = ref(null)//獲取列表節(jié)點
onMounted(() => {
listWrap.value.style.height = itemHeight.value * showNum.value + "px";//設置列表視圖模型的高度
});
const showList = computed(() => {
//獲取展示的列表
return list.value.slice(start.value, end.value);
});
const scrollListener = (() => {
//獲取滾動高度
let scrollTop = listWrap.value.scrollTop;
//開始的數(shù)組索引
start.value = Math.floor(scrollTop / itemHeight.value);
//結束索引
end.value = start.value + showNum.value;
List.value.style.transform = `translateY(${start.value * itemHeight.value}px)`//對列表項進行偏移
})
return {
...
};
},
效果:

節(jié)點變化
可以看到不論列表如何變化,列表dom的數(shù)量并沒有新增

總結
到此這篇關于vue長列表優(yōu)化之虛擬列表實現(xiàn)的文章就介紹到這了,更多相關vue虛擬列表實現(xiàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue中el-select中多選回顯數(shù)據(jù)后沒法重新選擇和更改的解決
本文主要介紹了vue中el-select中多選回顯數(shù)據(jù)后沒法重新選擇和更改解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-01-01
Element樹形控件el-tree懶加載并設置默認展開和選中的效果
本文主要介紹了Element樹形控件el-tree懶加載并設置默認展開和選中的效果,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-01-01
利用Vue v-model實現(xiàn)一個自定義的表單組件
本篇文章主要介紹了利用Vue v-model實現(xiàn)一個自定義的表單組件的相關知識。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04
element ui 表格動態(tài)列顯示空白bug 修復方法
今天小編就為大家分享一篇element ui 表格動態(tài)列顯示空白bug 修復方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09

