vue長(zhǎng)列表優(yōu)化之虛擬列表實(shí)現(xiàn)過程詳解
前言
應(yīng)用場(chǎng)景:后臺(tái)一次性發(fā)送上千條或更多數(shù)據(jù)給前臺(tái)
場(chǎng)景模擬:用戶發(fā)起一個(gè)請(qǐng)求,后臺(tái)發(fā)送了10w條數(shù)據(jù)
使用虛擬列表之前:前臺(tái)需要生成10w個(gè)dom節(jié)點(diǎn)用來渲染頁(yè)面
使用虛擬列表之后:前臺(tái)只需要生成少量dom節(jié)點(diǎn)(dom節(jié)點(diǎn)數(shù)量取決于前端視圖需要展示的數(shù)量),就可以實(shí)現(xiàn)對(duì)這10w條數(shù)據(jù)的視圖渲染
總之:虛擬列表就是固定dom節(jié)點(diǎn)數(shù)量,通過修改dom節(jié)點(diǎn)的內(nèi)容而達(dá)到不重新增加(或刪除)dom節(jié)點(diǎn)來實(shí)現(xiàn)列表的更新
實(shí)現(xiàn)原理
- 監(jiān)聽頁(yè)面滾動(dòng),獲取滾動(dòng)的高度scrolltop
- 根據(jù)scrolltop,可以知道當(dāng)前應(yīng)該展示哪一段數(shù)據(jù)(即獲取要展示數(shù)據(jù)的index)
- 根據(jù)當(dāng)前展示的數(shù)據(jù)在長(zhǎng)列表中的index,對(duì)列表進(jìn)行偏移
實(shí)現(xiàn)思路是這樣的:
設(shè)置列表初始值
- 需要展示給用戶的數(shù)量showNum
- 列表item的高度itemHeight
- 需要展示的第一條數(shù)據(jù)的下標(biāo)start
- 需要展示的最后一條數(shù)據(jù)的下標(biāo)end
- 通過start和end已經(jīng)showNum,我們可以得到需要展示的列表項(xiàng)showList,我們可以通過vue的計(jì)算屬性來實(shí)時(shí)獲取新的showList
建立列表視圖模型
- 給列表視圖設(shè)置高度ListWrapHeight
- 根據(jù)itemHeight和showNum,我們可以得到列表總高度ListHeight,我們必須要使得ListHeight高度大于ListWrapHeight,這樣才能實(shí)現(xiàn)滾動(dòng)
監(jiān)聽頁(yè)面滾動(dòng)
- 給列表視圖模型設(shè)置監(jiān)聽函數(shù),每當(dāng)列表視圖發(fā)生滾動(dòng),就執(zhí)行回調(diào),獲取滾動(dòng)高度scrolltop
- 通過scrolltop和itemHeight我們可以得到新的start以及end,從而獲取到新的showList
- 通過start和itemHeight我們可以給list設(shè)置偏移(translate),從而達(dá)到讓start對(duì)應(yīng)的數(shù)據(jù)展示在視圖模型的效果
注意:列表視圖模型和列表并不是一個(gè)東西,視圖模型表示者頁(yè)面供列表展示的一塊區(qū)域,而列表表示的是需要展示的列表項(xiàng)總高度
這是列表視圖模型
這是列表
列表中超出視圖模型的節(jié)點(diǎn)就被隱藏了
為什么限制了展示列表項(xiàng)的長(zhǎng)度(限制了dom數(shù)量),視圖模型還能持續(xù)滾動(dòng)?
給列表設(shè)置translate會(huì)增大列表的高度,既然list的高度變大了,那么視圖模型就可以繼續(xù)滾動(dòng)
實(shí)現(xiàn)代碼
? 以vue3為例(不管是vue2或是vue3,實(shí)現(xiàn)虛擬列表的核心代碼都是相同的,即監(jiān)聽滾動(dòng),賦新值)
<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); //長(zhǎng)列表數(shù)據(jù) const itemHeight = ref(props.itemHeight); //item高度 const showNum = ref(props.showNum); //展示的數(shù)據(jù) const start = ref(props.start); //滾動(dòng)過程中的開始索引 const end = ref(props.end); //滾動(dòng)過程中的結(jié)束索引 const listWrap = ref(null); //獲取列表視圖模型節(jié)點(diǎn) const List = ref(null)//獲取列表節(jié)點(diǎn) onMounted(() => { listWrap.value.style.height = itemHeight.value * showNum.value + "px";//設(shè)置列表視圖模型的高度 }); const showList = computed(() => { //獲取展示的列表 return list.value.slice(start.value, end.value); }); const scrollListener = (() => { //獲取滾動(dòng)高度 let scrollTop = listWrap.value.scrollTop; //開始的數(shù)組索引 start.value = Math.floor(scrollTop / itemHeight.value); //結(jié)束索引 end.value = start.value + showNum.value; List.value.style.transform = `translateY(${start.value * itemHeight.value}px)`//對(duì)列表項(xiàng)進(jìn)行偏移 }) return { ... }; },
效果:
節(jié)點(diǎn)變化
可以看到不論列表如何變化,列表dom的數(shù)量并沒有新增
總結(jié)
到此這篇關(guān)于vue長(zhǎng)列表優(yōu)化之虛擬列表實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)vue虛擬列表實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue實(shí)現(xiàn)不定高虛擬列表的示例詳解
- 不同場(chǎng)景下Vue中虛擬列表實(shí)現(xiàn)
- 詳解vue3中虛擬列表組件的實(shí)現(xiàn)
- Vue中虛擬列表的原理與實(shí)現(xiàn)詳解
- 基于Vue實(shí)現(xiàn)封裝一個(gè)虛擬列表組件
- 結(jié)合康熙選秀講解vue虛擬列表實(shí)現(xiàn)
- Vue 虛擬列表的實(shí)戰(zhàn)示例
- vue實(shí)現(xiàn)虛擬列表功能的代碼
- 使用 Vue 實(shí)現(xiàn)一個(gè)虛擬列表的方法
- vue簡(jiǎn)單實(shí)現(xiàn)一個(gè)虛擬列表的示例代碼
相關(guān)文章
vue-cli3在main.js中console.log()會(huì)報(bào)錯(cuò)的解決
這篇文章主要介紹了vue-cli3在main.js中console.log()會(huì)報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04vue組件定義,全局、局部組件,配合模板及動(dòng)態(tài)組件功能示例
這篇文章主要介紹了vue組件定義,全局、局部組件,配合模板及動(dòng)態(tài)組件功能,結(jié)合實(shí)例形式分析了vue.js中組件的定義、全局組件、局部組件、配合模板組件及動(dòng)態(tài)組件的相關(guān)使用方法與操作注意事項(xiàng),需要的朋友可以參考下2019-03-03Ant Design Vue全局對(duì)話確認(rèn)框(confirm)的回調(diào)不觸發(fā)
這篇文章主要介紹了Ant Design Vue全局對(duì)話確認(rèn)框(confirm)的回調(diào)不觸發(fā)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07vue.js+element-ui的基礎(chǔ)表單實(shí)例代碼
這篇文章主要介紹了vue.js+element-ui的基礎(chǔ)表單實(shí)例代碼,技術(shù)棧即html+vue.js+element-ui,而使用它們的方法也很簡(jiǎn)單,引入對(duì)應(yīng)的js和css文件即可,需要的朋友可以參考下2024-03-03利用Vue3和element-plus實(shí)現(xiàn)圖片上傳組件
element-plus提供了uploader組件,但是不好定制化。所以本文將利用Vue3和element-plus實(shí)現(xiàn)一個(gè)圖片上傳的組件,感興趣的可以了解一下2022-03-03使用vue.js2.0 + ElementUI開發(fā)后臺(tái)管理系統(tǒng)詳細(xì)教程(一)
這篇文章主要介紹了使用vue.js2.0 + ElementUI開發(fā)后臺(tái)管理系統(tǒng)詳細(xì)教程(一)的相關(guān)資料,需要的朋友可以參考下2017-01-01Vue中的v-model,v-bind,v-on的區(qū)別解析
vue.js是一套構(gòu)建用戶界面的框架,只關(guān)注視圖層,它不僅易于上手,還便于與第三方庫(kù)或既有項(xiàng)目整合,vue.js有配套的第三方類庫(kù),可以整合起來做大型項(xiàng)目的開發(fā),這篇文章主要介紹了v-model,v-bind,v-on的區(qū)別,需要的朋友可以參考下2022-12-12