淺談el-table中使用虛擬列表對對表格進行優化

前言

我們會經常使用表格,如果數據量大就直接可以分頁,但是不可避免的會出現一些需要一頁要展示很多條的情況,或者不用分頁。

這個時候如果純展示還好一點,列表裡如果加上可編輯,就會變得卡的不行,點個下拉框,下拉框好久才會彈出來。這樣是十分影響用戶使用。

解決思路

  • 首先我考慮是不是由於數據加載太慢導致的頁面卡頓,於是我采用瞭滾動加載的方式,首先獲取數據後,先加載100條數據。滾動的時候再加載到頁面中,這樣分批次加載,就會減輕首次加載數據量太大的壓力。剛開始是沒有問題的,等到後面數據越來越多的時候,再點擊表格中可編輯的下拉框時候就明顯感覺到頁面變卡瞭。
  • 後面想的就是如果我隻加載頁面看得到的區域的數據,那麼應該就能解決頁面卡頓的問題瞭。

具體實現

剛開始加載時候獲取10/20條數據(這個可以通過計算,每一行的高度/頁面顯示數據的高度,也可以固定數值),滾動的時候監聽滾動條,根據滾動的距離來計算顯示頁面的數據。

需要滿足的必備條件

列表的總高度

總數據長度 × 每一行的高度

如果隻有頁面顯示的高度,就無法滾動獲取新的數據

每一行的高度

如果是固定高度可以寫死數值
如果是動態高度可以通過計算

滾動的偏移量

當前滾動的距離 – ( 當前滾動的距離 % 每一行的高度)

頁面展示的數據的起始索引及結束索引

起始索引剛開始為0
滾動的過程中  起始索引 = Math.floor(當前滾動的距離 / 每一行的高度)

代碼步驟

<div class="main-inner-content">
    <el-table :data="visibleData" :style="{'min-height': gradingEditor ? listHeight+'px':'100%'}" id="dataTable">

    </el-table>
</div>

computed: {
        // //列表總高度
        listHeight () {
            // tableData 是獲取接口的總數據
            return this.tableData.length * this.itemSize;
        },
        // //偏移量對應的style
        getTransform () {
            return `translate3d(0,${this.startOffset}px,0)`;
        },
        //獲取真實顯示列表數據
        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,
        //結束索引
        end: null,
    };
},
methods:{
    handleScroll () {
        // 這個是滾動的盒子,如果滾動的位置是table,這裡也對應的改下就好瞭,還有偏移量賦值的地方
        let scrollTop = document.getElementById('main-inner-content').scrollTop;
        // //此時的開始索引
        this.start = Math.floor(scrollTop / this.itemSize);
        if (this.start < 0) this.start = 0;
        // //此時的結束索引
        this.end = this.start + 10;
        // //此時的偏移量
        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) //  清除滾條滾動事件
}

頁面滾動的時候一直隻會加載十條數據
通過偏移量來確定頁面展示

問題

我是給整個el-table設置瞭總高度,然後給下面列表項的盒子設置的偏移量。如果頁面是在不刷新的情況下需要重新獲取數據(比如分頁),一定要將數據初始化,否則頁面會直接展示之前的數據,或者頁面出現空白。

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

為瞭方便計算及使用,頁面每一行的高度我采用的是固定高度的方式使用的是超出省略的方式,但是部署預發環境後會發現-webkit-box-orient: vertical這句代碼直接就沒有瞭,不顯示。
解決辦法:寫行內樣式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

到此這篇關於淺談el-table中使用虛擬列表對對表格進行優化的文章就介紹到這瞭,更多相關el-table表格優化內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: