vue?長(zhǎng)列表數(shù)據(jù)刷新的實(shí)現(xiàn)及思考
開篇
通過 vue 進(jìn)行列表展示的時(shí)候如果數(shù)據(jù)太多可能會(huì)卡頓,這里通過滑動(dòng)計(jì)算只創(chuàng)建跟刷新可見部分 dom 元素,這里僅僅代表著復(fù)用思路
一、效果展示
兩列均為局部可視范圍內(nèi)數(shù)據(jù)刷新
二、代碼
實(shí)現(xiàn)的主要思路:
1、提前保留可視div的高度,計(jì)算出可視高度能填滿情況下最少的單元格條數(shù);
2、根據(jù)提供的每個(gè)單元格高度和總數(shù)據(jù)條數(shù)計(jì)算出總的可滑動(dòng)div高度,使其可以滑動(dòng);
3、在上述可滑動(dòng)div內(nèi)部再包裹一層div,此節(jié)點(diǎn)的作用就是在滑動(dòng)過程中,改變自身的 top 值,使之在父節(jié)點(diǎn)滑動(dòng)中始終出現(xiàn)在父節(jié)點(diǎn)的可視區(qū)域內(nèi)。
4、根據(jù)滑動(dòng)的距離更新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 + '個(gè)')}) } 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ù)期滑動(dòng)的最大高度 this.scrollTop = 0//當(dāng)前滾動(dòng)距離 this.beginRefreshDataDistance = expectationCellHeight//滑動(dòng)觸發(fā)刷新數(shù)據(jù)最小距離,這里僅為一個(gè)單元格高度 // 開始填充數(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é)點(diǎn)之間的數(shù)據(jù) let currentData = this.totalData.slice(this.startIndex,this.endIndex) //給vue提供數(shù)據(jù) this.refreshDataCallBack(currentData) } // 監(jiān)聽滾動(dòng) this.addListenerScroll = function(){ //父節(jié)點(diǎn) let parentNode = this.el.parentNode //第一個(gè)子節(jié)點(diǎn)(改變其top值實(shí)現(xiàn)始終在父節(jié)點(diǎn)的可視區(qū)域內(nèi)) let firstChild = this.el.firstChild let scrollingEvent = ()=>{ let scrollTop = parentNode.scrollTop //滑動(dòng)的距離超過規(guī)定的閥值或者滑動(dòng)距離為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,實(shí)現(xiàn)屏幕相對(duì)位置不變 firstChild.style.top = scrollTop + 'px' //回傳數(shù)據(jù)源 this.getCurrentShowDatas() this.scrollTop = scrollTop } } //開始監(jiān)聽滾動(dòng) parentNode.addEventListener("scroll", scrollingEvent) } }
復(fù)用其實(shí)是由vue來處理的,這里僅是將刷新數(shù)據(jù)進(jìn)行了篩選以達(dá)到刷新最小數(shù)據(jù)條數(shù)的目的,這里僅僅是簡(jiǎn)單的實(shí)現(xiàn)思路,希望對(duì)大家有幫助,更多關(guān)于vue 長(zhǎng)列表數(shù)據(jù)刷新的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決element-ui中Popconfirm氣泡確認(rèn)框的事件不生效問題
這篇文章主要介紹了解決element-ui中Popconfirm氣泡確認(rèn)框的事件不生效問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07ElementUI的this.$notify.close()調(diào)用不起作用的解決
本文主要介紹了ElementUI的this.$notify.close()調(diào)用不起作用的解決,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08表格Table實(shí)現(xiàn)前端全選所有功能方案示例(包含非當(dāng)前頁)
這篇文章主要為大家介紹了表格Table實(shí)現(xiàn)前端全選所有功能,包括非當(dāng)前頁的方案示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-02-02Vue+mui實(shí)現(xiàn)圖片的本地緩存示例代碼
這篇文章主要介紹了Vue+mui實(shí)現(xiàn)圖片的本地緩存的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-05-05vue實(shí)現(xiàn)條件判斷動(dòng)態(tài)綁定樣式的方法
今天小編就為大家分享一篇vue實(shí)現(xiàn)條件判斷動(dòng)態(tài)綁定樣式的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09Vue+ElementUI實(shí)現(xiàn)從后臺(tái)動(dòng)態(tài)填充下拉框的示例代碼
本文主要介紹了Vue+ElementUI實(shí)現(xiàn)從后臺(tái)動(dòng)態(tài)填充下拉框的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02vue關(guān)于重置表單數(shù)據(jù)出現(xiàn)undefined的解決
這篇文章主要介紹了vue關(guān)于重置表單數(shù)據(jù)出現(xiàn)undefined的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09