淺談el-table中使用虛擬列表對(duì)對(duì)表格進(jìn)行優(yōu)化
前言
我們會(huì)經(jīng)常使用表格,如果數(shù)據(jù)量大就直接可以分頁,但是不可避免的會(huì)出現(xiàn)一些需要一頁要展示很多條的情況,或者不用分頁。
這個(gè)時(shí)候如果純展示還好一點(diǎn),列表里如果加上可編輯,就會(huì)變得卡的不行,點(diǎn)個(gè)下拉框,下拉框好久才會(huì)彈出來。這樣是十分影響用戶使用。
解決思路
- 首先我考慮是不是由于數(shù)據(jù)加載太慢導(dǎo)致的頁面卡頓,于是我采用了滾動(dòng)加載的方式,首先獲取數(shù)據(jù)后,先加載100條數(shù)據(jù)。滾動(dòng)的時(shí)候再加載到頁面中,這樣分批次加載,就會(huì)減輕首次加載數(shù)據(jù)量太大的壓力。剛開始是沒有問題的,等到后面數(shù)據(jù)越來越多的時(shí)候,再點(diǎn)擊表格中可編輯的下拉框時(shí)候就明顯感覺到頁面變卡了。
- 后面想的就是如果我只加載頁面看得到的區(qū)域的數(shù)據(jù),那么應(yīng)該就能解決頁面卡頓的問題了。
具體實(shí)現(xiàn)
剛開始加載時(shí)候獲取10/20條數(shù)據(jù)(這個(gè)可以通過計(jì)算,每一行的高度/頁面顯示數(shù)據(jù)的高度,也可以固定數(shù)值),滾動(dòng)的時(shí)候監(jiān)聽滾動(dòng)條,根據(jù)滾動(dòng)的距離來計(jì)算顯示頁面的數(shù)據(jù)。
需要滿足的必備條件
列表的總高度
總數(shù)據(jù)長度 × 每一行的高度
如果只有頁面顯示的高度,就無法滾動(dòng)獲取新的數(shù)據(jù)
每一行的高度
如果是固定高度可以寫死數(shù)值
如果是動(dòng)態(tài)高度可以通過計(jì)算
滾動(dòng)的偏移量
當(dāng)前滾動(dòng)的距離 - ( 當(dāng)前滾動(dòng)的距離 % 每一行的高度)
頁面展示的數(shù)據(jù)的起始索引及結(jié)束索引
起始索引剛開始為0
滾動(dòng)的過程中 起始索引 = Math.floor(當(dāng)前滾動(dòng)的距離 / 每一行的高度)
代碼步驟
<div class="main-inner-content"> <el-table :data="visibleData" :style="{'min-height': gradingEditor ? listHeight+'px':'100%'}" id="dataTable"> </el-table> </div>
computed: { // //列表總高度 listHeight () { // tableData 是獲取接口的總數(shù)據(jù) return this.tableData.length * this.itemSize; }, // //偏移量對(duì)應(yīng)的style getTransform () { return `translate3d(0,${this.startOffset}px,0)`; }, //獲取真實(shí)顯示列表數(shù)據(jù) visibleData () { let tableBody = document.querySelector('#dataTable >.el-table__body-wrapper') if (tableBody) { tableBody.style.transform = this.getTransform } return this.tableData.slice(this.start, Math.min(this.end, this.tableData.length)); } }, data() { return { tableData:[], //偏移量 startOffset: 0, //起始索引 start: 0, //結(jié)束索引 end: null, }; }, methods:{ handleScroll () { // 這個(gè)是滾動(dòng)的盒子,如果滾動(dòng)的位置是table,這里也對(duì)應(yīng)的改下就好了,還有偏移量賦值的地方 let scrollTop = document.getElementById('main-inner-content').scrollTop; // //此時(shí)的開始索引 this.start = Math.floor(scrollTop / this.itemSize); if (this.start < 0) this.start = 0; // //此時(shí)的結(jié)束索引 this.end = this.start + 10; // //此時(shí)的偏移量 this.startOffset = scrollTop - (scrollTop % this.itemSize); this.startOffset = this.startOffset > this.itemSize ? this.startOffset - this.itemSize : 0; } }, mounted(){ window.addEventListener("scroll", this.handleScroll, true); }, destroyed(){ window.removeEventListener('scroll', this.handleScroll, true) // 清除滾條滾動(dòng)事件 }
頁面滾動(dòng)的時(shí)候一直只會(huì)加載十條數(shù)據(jù)
通過偏移量來確定頁面展示
問題
我是給整個(gè)el-table設(shè)置了總高度,然后給下面列表項(xiàng)的盒子設(shè)置的偏移量。如果頁面是在不刷新的情況下需要重新獲取數(shù)據(jù)(比如分頁),一定要將數(shù)據(jù)初始化,否則頁面會(huì)直接展示之前的數(shù)據(jù),或者頁面出現(xiàn)空白。
document.querySelector('#main-inner-content').scrollTop = 0 this.start = 0 this.startOffset = 0 this.end = this.start + 10; let tableBody = document.querySelector('#dataTable >.el-table__body-wrapper') tableBody.style.transform = this.getTransform
為了方便計(jì)算及使用,頁面每一行的高度我采用的是固定高度的方式使用的是超出省略的方式,但是部署預(yù)發(fā)環(huán)境后會(huì)發(fā)現(xiàn)-webkit-box-orient: vertical這句代碼直接就沒有了,不顯示。
解決辦法:寫行內(nèi)樣式style="-webkit-box-orient: vertical" 這樣就可以了
.omit-text { word-wrap: break-word; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
參考
https://juejin.cn/post/6844903982742110216#heading-4
https://codesandbox.io/s/virtuallist-1-forked-sd2xn?file=/src/components/VirtualList.vue:1487-1652
到此這篇關(guān)于淺談el-table中使用虛擬列表對(duì)對(duì)表格進(jìn)行優(yōu)化的文章就介紹到這了,更多相關(guān)el-table表格優(yōu)化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue backtop組件的實(shí)現(xiàn)完整代碼
這篇文章主要介紹了vue backtop組件的實(shí)現(xiàn)完整代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04Xx-vue自定義指令實(shí)現(xiàn)點(diǎn)擊水波紋漣漪效果
這篇文章主要為大家介紹了Xx-vue自定義指令實(shí)現(xiàn)點(diǎn)擊水波紋漣漪效果,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07electron-builder打包vue2項(xiàng)目問題總結(jié)
這篇文章主要介紹了electron-builder打包vue2項(xiàng)目問題總結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-08-08Vue.js+express利用切片實(shí)現(xiàn)大文件斷點(diǎn)續(xù)傳
斷點(diǎn)續(xù)傳就是要從文件已經(jīng)下載的地方開始繼續(xù)下載,本文主要介紹了Vue.js+express利用切片實(shí)現(xiàn)大文件斷點(diǎn)續(xù)傳,具有一定的參考價(jià)值,感興趣的可以了解下2023-05-05vue項(xiàng)目實(shí)現(xiàn)通過ip地址訪問和localhost訪問方式
這篇文章主要介紹了vue項(xiàng)目實(shí)現(xiàn)通過ip地址訪問和localhost訪問方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09Vue3 響應(yīng)式高階用法之triggerRef()的使用
在Vue3響應(yīng)式系統(tǒng)中,shallowRef僅追蹤頂層屬性的變化,當(dāng)需要對(duì)內(nèi)層屬性作出反應(yīng)時(shí),可使用triggerRef()方法手動(dòng)觸發(fā)更新,本文介紹了triggerRef()的應(yīng)用場景、基本用法、功能和最佳實(shí)踐,感興趣的可以了解一下2024-09-09