<template>
<div class="my-table"
v-loading="isLoading"
element-loading-text="拼命加载中..."
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(7, 11, 44, 0.8)">
<!-- el-table 增加key 重新生成实例会重置滚动条位置回复初始位置 -->
<el-table
:key="isLoading"
ref="table"
:data="getTableData"
:empty-text="isLoading ? '' : '暂无数据'"
style="width: 100%"
height="99.9%"
>
<el-table-column
v-for="(item, index) in tableHeader"
:key="index"
:prop="item.prop"
:label="item.label"
align="center"
:show-overflow-tooltip="true"
min-width="110px"
>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data () {
return {
currentIndex: 1, // 定位截取索引
isLoading: false,
tableHeader: [{
prop: 'name',
label: '区域'
}, {
prop: 'cameraNum',
label: '摄像头数'
}, {
prop: 'onlineNum',
label: '在线数'
}, {
prop: 'offlineNum',
label: '离线数'
}, {
prop: 'noCamera',
label: '无摄像头'
}], // 表格的表头
tableData: [] // 表格的值
}
},
methods: {
async updateTableData (code = '', level = '') {
this.tableData = []
this.currentIndex = 1
this.isLoading = true
const res = await new Promise((reslove,reject)=>{
setTimeout(() => {
reslove({
data: Array(1000).fill({}).map((item,index)=>({index}))
}) // 模拟大数据量
}, 1000);
})
this.tableData = res.data
this.isLoading = false
this.virtualScroll() // 虚拟滚动处理:大数据量
},
virtualScroll () {
if (!this.tableData.length) {
return
}
this.$nextTick(() => {
const elBodyWrapper = this.$refs.table.$el.querySelector('.el-table__body-wrapper') // 滚动容器dom
const h = elBodyWrapper.querySelectorAll('.el-table__cell')[0].offsetHeight // 单行高度
// 方案1:动态增加标签,给标签设置高度,从而撑开容器elBodyWrapper整体高度
/**********方案1代码开始**********/
const i = document.createElement('i') // 通过一个标签撑开容器内容
i.style.width = '0'
i.style.height = this.tableData.length * h + 'px' // 设置容器内容整体高度
elBodyWrapper.append(i)
// 添加滚动监听
elBodyWrapper.addEventListener('scroll', () => {
let s = elBodyWrapper.scrollTop // 滚动条位置
const c = Math.floor(s / h) // 滚动后定位索引
// 判断是否存在横向滚动条时且处于置底时
if (s >= (this.tableData.length * h) - elBodyWrapper.offsetHeight - 16) {
s = (this.tableData.length * h) - elBodyWrapper.offsetHeight
}
if (s <= 0) {
s = 0
}
// 更新定位索引
this.currentIndex = c + 1
elBodyWrapper.querySelector('.el-table__body').style.transform = `translateY(${s}px)`
})
/**********方案1代码结束**********/
// 方案2:给el-table__body设置一个动态的paddingTop值,视觉上做一个虚拟占位(必须保持一个较大的截取长度,保证初始表格出现滚动条,否则该方案存在问题)
/**********方案2代码开始**********/
// 添加滚动监听
elBodyWrapper.addEventListener('scroll', () => {
let s = elBodyWrapper.scrollTop // 滚动条位置
const c = Math.floor(s / h) // 滚动后定位索引
// 判断是否存在横向滚动条时且处于置底时
if (s >= (this.tableData.length * h) - elBodyWrapper.offsetHeight - 16) {
s = (this.tableData.length * h) - elBodyWrapper.offsetHeight
}
if (s <= 0) {
s = 0
}
// 更新定位索引
this.currentIndex = c + 1
elBodyWrapper.querySelector('.el-table__body').style.paddingTop = `${s}px`
})
/**********方案2代码结束**********/
})
}
},
computed: {
getTableData () {
// 每次根据定位索引currentIndex截取16位长度的数组数据
return this.tableData.slice(this.currentIndex - 1, this.currentIndex + 15)
}
},
mounted () {
this.updateTableData()
}
}
</script>
<style lang="less" scoped>
</style>
console