vue?長列表數(shù)據(jù)刷新的實現(xiàn)及思考
開篇
通過 vue 進(jìn)行列表展示的時候如果數(shù)據(jù)太多可能會卡頓,這里通過滑動計算只創(chuàng)建跟刷新可見部分 dom 元素,這里僅僅代表著復(fù)用思路
一、效果展示
兩列均為局部可視范圍內(nèi)數(shù)據(jù)刷新

二、代碼
實現(xiàn)的主要思路:
1、提前保留可視div的高度,計算出可視高度能填滿情況下最少的單元格條數(shù);
2、根據(jù)提供的每個單元格高度和總數(shù)據(jù)條數(shù)計算出總的可滑動div高度,使其可以滑動;
3、在上述可滑動div內(nèi)部再包裹一層div,此節(jié)點的作用就是在滑動過程中,改變自身的 top 值,使之在父節(jié)點滑動中始終出現(xiàn)在父節(jié)點的可視區(qū)域內(nèi)。
4、根據(jù)滑動的距離更新vue數(shù)據(jù),但是也只是更新能填滿可視區(qū)域最小條數(shù)。
<div class="main">
<div v-for="(dom) in longListEl" :key="dom.id" class="longList">
<div :id="dom.id" class="contain">
<div style="width: calc(100% - 20px);position: relative;">
<div :style="{height:`${expectationCellHeight}px`}" v-for="(item,index) in dom.data" :key="item.id">
{{ item.title }}
</div>
</div>
</div>
</div>
</div>
export default {
data() {
return {
longListData:[],
expectationCellHeight:40,
longListEl:[{id:'contain',data:[]},{id:'contain1',data:[]}],
longListDataManages:[]
};
},
mounted() {
for(let index = 0;index < 250000;index ++){
this.longListData.push({id:index,title:('我是第' + index + '個')})
}
this.$nextTick(()=>{
this.longListEl.forEach((dom)=>{
let containEl = document.getElementById(dom.id)
if(containEl){
this.longListDataManages.push(new LongListDataManage(containEl,this.longListData,this.expectationCellHeight,(data)=>{
dom.data = data
}))
}
})
})
},
methods: {
},
};
function LongListDataManage(el,totalData,expectationCellHeight,refreshDataCallBack){
this.el = el//需要操作的dom
this.startIndex = 0//數(shù)據(jù)源的開始索引
this.endIndex = 0//數(shù)據(jù)源的結(jié)束索引
this.containElHeight = el ? el.offsetHeight : 0//可視區(qū)域高度
this.totalData = totalData//全部數(shù)據(jù)源
this.refreshDataCallBack = refreshDataCallBack//數(shù)據(jù)刷新回調(diào)
this.expectationCellHeight = expectationCellHeight//預(yù)期的單元cell高度
this.expectationCellFullScreenNum = 0//預(yù)期可視區(qū)域展示的單元條數(shù)
this.expectationTotalHeight = 0//預(yù)期滑動的最大高度
this.scrollTop = 0//當(dāng)前滾動距離
this.beginRefreshDataDistance = expectationCellHeight//滑動觸發(fā)刷新數(shù)據(jù)最小距離,這里僅為一個單元格高度
// 開始填充數(shù)據(jù)
this.begin = function(){
this.initData()
this.getCurrentShowDatas()
this.addListenerScroll()
}
// 初始化參數(shù)
this.initData = function(){
//總高度設(shè)定
this.expectationTotalHeight = this.totalData.length * this.expectationCellHeight
this.el.style.height = this.expectationTotalHeight + 'px'
//數(shù)據(jù)源的結(jié)束索引設(shè)定(向上取整)
this.endIndex = this.expectationCellFullScreenNum = Math.ceil((this.containElHeight / this.expectationCellHeight) + 0.1)
}
// 開始獲取當(dāng)前需要展示的區(qū)間
this.getCurrentShowDatas = function(){
//截取數(shù)據(jù)源開始跟結(jié)束節(jié)點之間的數(shù)據(jù)
let currentData = this.totalData.slice(this.startIndex,this.endIndex)
//給vue提供數(shù)據(jù)
this.refreshDataCallBack(currentData)
}
// 監(jiān)聽滾動
this.addListenerScroll = function(){
//父節(jié)點
let parentNode = this.el.parentNode
//第一個子節(jié)點(改變其top值實現(xiàn)始終在父節(jié)點的可視區(qū)域內(nèi))
let firstChild = this.el.firstChild
let scrollingEvent = ()=>{
let scrollTop = parentNode.scrollTop
//滑動的距離超過規(guī)定的閥值或者滑動距離為0進(jìn)行數(shù)據(jù)源重置
if(Math.abs(scrollTop - this.scrollTop) >= this.beginRefreshDataDistance || scrollTop <= 0){
//更改數(shù)據(jù)源區(qū)間索引
this.startIndex = Math.ceil(scrollTop / this.expectationCellHeight)
this.endIndex = this.startIndex + this.expectationCellFullScreenNum
//上下平移可視區(qū)域展示dom,實現(xiàn)屏幕相對位置不變
firstChild.style.top = scrollTop + 'px'
//回傳數(shù)據(jù)源
this.getCurrentShowDatas()
this.scrollTop = scrollTop
}
}
//開始監(jiān)聽滾動
parentNode.addEventListener("scroll", scrollingEvent)
}
}
復(fù)用其實是由vue來處理的,這里僅是將刷新數(shù)據(jù)進(jìn)行了篩選以達(dá)到刷新最小數(shù)據(jù)條數(shù)的目的,這里僅僅是簡單的實現(xiàn)思路,希望對大家有幫助,更多關(guān)于vue 長列表數(shù)據(jù)刷新的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue面試created中兩次數(shù)據(jù)修改會觸發(fā)幾次頁面更新詳解
這篇文章主要為大家介紹了vue面試created中兩次數(shù)據(jù)修改會觸發(fā)幾次頁面更新問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
vue的axios使用post時必須使用qs.stringify而get不用問題
這篇文章主要介紹了vue的axios使用post時必須使用qs.stringify而get不用問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01
Vue3?封裝?Element?Plus?Menu?無限級菜單組件功能的詳細(xì)代碼
本文分別使用?SFC(模板方式)和?tsx?方式對?Element?Plus?*el-menu*?組件進(jìn)行二次封裝,實現(xiàn)配置化的菜單,有了配置化的菜單,后續(xù)便可以根據(jù)路由動態(tài)渲染菜單,對Vue3?無限級菜單組件相關(guān)知識感興趣的朋友一起看看吧2022-09-09
使用vue-virtual-scroller遇到的問題及解決
這篇文章主要介紹了使用vue-virtual-scroller遇到的問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03

