vue實現(xiàn)滾動加載的表格
實現(xiàn)效果

滾動加載知識儲備
參考ant-design-vue中l(wèi)ist滾動加載的思路,使用vue-infinite-scroll加上vue-virtual-scroller作為解決方案。
組件封裝
因為整個系統(tǒng)使用的框架是ant-dsign-vue,所以組件封裝的變量命名風格盡可能的與a-table保持一致。
1. 組件命名
XScrollTable.vue
2. 提供的props
必填字段:
dataSource -- 數(shù)據(jù)源
columns -- 表格展示的列信息,插槽用法和a-table不完全一樣,下面會提到。
itemSize -- 每行數(shù)據(jù)的高度
選填字段:
rowKey -- 數(shù)據(jù)主鍵標識,默認為'key'
height -- 表格展示區(qū)域的高度,默認為500
pageSize -- 表格滾動每次滾動加載的數(shù)據(jù)量,默認為30
infiniteScrollDistance -- 表格觸發(fā)加載的距離條件,默認為10
rowSelection -- 表格多選配置,已處理的屬性有selectedRowKeys、onChange、width。默認為null,不展示多選。
3.使用舉例
首先初始化10000條數(shù)據(jù),放在表格中進行顯示。
let data = new Array(10000).fill(1);
data = data.map((item1, index) => {
let item = {};
item.id = index;
item.age = "姓名";
item.address = "地址";
return item;
});
export default data;
注意:這里之所以加了fill(1),是因為通過Array構造函數(shù)產(chǎn)生的數(shù)據(jù)全是empty,沒有數(shù)組索引,無法進行map循環(huán)。
加載表格
<x-scroll-table
style="margin-top: 10px"
row-key="id"
:itemSize="22"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,width:50}"
:columns="columns"
:dataSource="data">
<template slot="action" slot-scope="{record,text}">
<a @click="handleDetail(record)">詳情</a>
</template>
</x-scroll-table>
組件封裝總結
1.盡可能地使用computed計算屬性
雖然只是簡單地封裝了表格,但還是需要定義了很多的屬性,使用計算屬性代替在data里定義變量,可以減少變量的維護工作量。
整個組件只定義了一個page變量,其它都是使用計算屬性的方式。
data() {
return {
// 當前展示頁數(shù)
page: 1,
};
},
舉個栗子:
通過page屬性定義一個計算屬性來表示當前已經(jīng)加載的數(shù)據(jù)量
// 展示的最大下標數(shù)量,存在比總數(shù)據(jù)條數(shù)多的情況,使用slice解決這個問題
lastIndex() {
return this.pageSize * this.page;
},
通過這個計算屬性同時衍生出其他的計算屬性
// 表示表格數(shù)據(jù)是否已經(jīng)加載完畢
busy() {
return this.lastIndex >= this.dataSource.length;
},
// 當前已經(jīng)加載到RecycleScroller滾動組件的數(shù)據(jù)
tableData() {
return this.dataSource.slice(0, this.lastIndex);
},
通過一個page屬性衍生出一系列的計算屬性,我只需要維護page屬性,其他都是自動計算的。
2.給表格提供插槽
首先通過表格傳入的columns參數(shù),計算出需要渲染的列,這里同樣使用計算屬性。
// 將列數(shù)組轉為列對象,將columnFieldKey值作為鍵,數(shù)組項作為值
columnMap() {
return this.columns.reduce((returnValue, cur) => {
returnValue[cur[columnFieldKey]] = cur;
return returnValue;
}, {});
},
// 取數(shù)組里的列鍵值--columnFieldKey
columnKeys() {
return this.columns
.map(item => item[columnFieldKey]);
},
在template中遍歷
<div v-for="(key) of columnKeys"
class="ellipsis-cell"
:key="key"
:style="itemStyle(columnMap[key])"
>
<slot v-if="izSlotRender(columnMap[key])"
:name="columnMap[key].scopedSlots.customRender"
:record="row"
:text="row[key]">
</slot>
<span v-else :title="row[key]">{{ renderItem(row, index, key) }}</span>
</div>
// 是否使用插槽渲染
izSlotRender(item) {
return item.scopedSlots && item.scopedSlots.customRender;
},
如果在定義columns時傳入了scopedSlots和customRender,將使用插槽渲染。
但是這里存在和ant-design-vue中表格插槽渲染不一樣的地方。
我通過slot標簽定義的插槽,在父組件獲取插槽參數(shù)的時候,只能使用slot-scope="{record,text}"對象解構的方式。而ant-design-vue表格是可以直接使用slot-scope="record,text"獲取參數(shù)的。
另一種滾動加載數(shù)據(jù)的實現(xiàn)
table數(shù)據(jù)多的時候打開頁面會加載一會才顯示數(shù)據(jù),這樣體驗不好,所以要做滾動加載數(shù)據(jù)
<el-table :data="materielList" style="width: 100%" class="familyDataDetail" height="250">
<el-table-column prop="eventId" label="事件ID">
<template scope="scope">
<label>{{eventMap[scope.row.eventId] == null ? '--': eventMap[scope.row.eventId].sn}}</label>
</template>
</el-table-column>
<el-table-column prop="title" label="對應事件">
<template scope="scope">
<label>{{eventMap[scope.row.eventId] == null ? '--': eventMap[scope.row.eventId].title}}</label>
</template>
</el-table-column>
<el-table-column prop="age" label="負責人">
<template scope="scope">
<label>{{eventMap == null || eventMap[scope.row.eventId] == null || eventMap[scope.row.eventId].personalInformation == null ? '--':
eventMap[scope.row.eventId].personalInformation.name}}</label>
</template>
</el-table-column>
<el-table-column prop="birthday" label="物料名稱">
<template scope="scope">
<label>{{materirlName}}</label>
</template>
</el-table-column>
<el-table-column prop="idcardNo" label="狀態(tài)">
<template scope="scope">
<label>{{formatType(scope.row.type)}}</label>
</template>
</el-table-column>
<el-table-column prop="relationship" label="數(shù)量">
<template scope="scope">
<label>{{formatUseNum(scope.row.useNum)}}</label>
</template>
</el-table-column>
<el-table-column prop="ethtic" label="使用時間">
<template scope="scope">
<label>{{changeTime(scope.row.createOn)}}</label>
</template>
</el-table-column>
</el-table>
下面是js部分
methods: {
init (param) {
let id = param.param && param.param.id
if(id){
this.start = 0
MaterialRecordService.query({param: {baseId: this.baseId, materialId: id},start: this.start,limit: 30}).then(rsp => {//初次請求數(shù)據(jù),30條
this.start += 30
this.materielList = rsp.data
MissionEventService.microList({ids: rsp.data.map(n => n.eventId)}).then(rsp3 => {
this.eventMap = {}
rsp3.data.forEach(n => (this.eventMap[n.id] = n))
})
})
}
},
onScroll() {
let inner = document.querySelector('.el-table__body-wrapper');
if(inner.scrollHeight - inner.scrollTop <= inner.clientHeight){//為true時證明已經(jīng)到底,可以請求接口
if(this.flag){//設一個滾動事件的開關,(在data里面聲明 flag: true)默認為true
this.flag = false
MaterialRecordService.query({param: {baseId: this.baseId, materialId: this.entity.id},start: this.start,limit:30}).then(rsp => {//每次加載30條
this.materielList = this.materielList.concat(rsp.data)
this.start += 30
this.flag = true
MissionEventService.microList({ids: rsp.data.map(n => n.eventId)}).then(rsp3 => {
rsp3.data.forEach(n => (this.eventMap[n.id] = n))
})
})
}
}
}
},
mounted () {
this.init({...this.param})<br> //監(jiān)聽表格dom對象的滾動事件
document.querySelector('.el-table__body-wrapper').addEventListener('scroll', this.onScroll);
}
在這里我要說明一下監(jiān)聽的dom對象是哪一個

我還要解釋下scrollHeight、scrollTop、clientHeight這三個屬性

這是我截的別人的圖加了幾筆
scrollHeight:網(wǎng)頁正文全文高度,
scrollTop:網(wǎng)頁滾動的高度,
clientHeight:網(wǎng)頁可視區(qū)域的高度
以上就是vue實現(xiàn)滾動加載的表格的詳細內(nèi)容,更多關于vue 滾動加載的表格的資料請關注腳本之家其它相關文章!
相關文章
vue3實戰(zhàn)教程之a(chǎn)xios的封裝和環(huán)境變量
這篇文章主要給大家介紹了關于vue3實戰(zhàn)教程之a(chǎn)xios的封裝和環(huán)境變量的相關資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2022-02-02
vue?長列表數(shù)據(jù)刷新的實現(xiàn)及思考
這篇文章主要為大家介紹了vue?長列表數(shù)據(jù)刷新的實現(xiàn)及思考,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04
vue+el-table點擊表頭實現(xiàn)改變其當前樣式
這篇文章主要介紹了vue+el-table點擊表頭實現(xiàn)改變其當前樣式問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
vue使用el-table 添加行手動填寫數(shù)據(jù)和刪除行及提交保存功能
遇到這樣的需求點擊新增按鈕實現(xiàn)下列彈窗的效果,點擊添加行新增一行,點擊刪除進行刪除行,點擊提交將數(shù)據(jù)傳遞到后端進行保存,怎么實現(xiàn)的呢,下面通過實例代碼給大家詳細講解,感興趣的朋友一起看看吧2023-12-12

