问题描述
版本:2.15.13
el-table在使用合计功能及固定列功能的同时,由于固定列的结构是固定区域增加了div加上定位,用来盖住下面的内容。当使用了合计功能的时候滚动条的区域在el-table__body-wrapper会导致固定列区域下的滚动条被挡住,当固定区域较大数据量较多的情况下存在滚动条全部滚动到固定区域无法回滚的问题。如下图:
建议修改方案
1.当使用了合计功能把对el-table__body-wrapper进行超出隐藏,将滚动条加到合计区域el-table__footer-wrapper,此时通过监听合计区域的滚动事件来触发el-table__body-wrapper的滚动。
2.使用虚拟滚动条:为el-table添加虚拟滚动条。通过虚拟滚动条的滚动来触发el-table__footer-wrapper和el-table__body-wrapper的滚动。
以上只针对于横向滚动条的提出问题
针对于以上处理需要隐藏原有滚动条,如果只考虑x方向会存在偏移问题如下图:
当前解决
针对于当前项目实现修改思路,自己写一个盒子盖住横向滚动条,然后内部元素宽度与table实际宽度保持一致,监听盒子滚动事件,盒子滚动多少,带动el-table滚动多少。测试代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style>
body {
margin: 100px;
}
#yh-scrollbar-box {
background: #F8F9FB;
box-sizing: border-box;
height: 15px;
position: absolute;
width: 100%;
left: 0;
z-index: 5;
overflow-x: scroll;
}
</style>
</head>
<body>
<div id="app">
<el-table :data="tableData" border :height="700" ref="accountTable" show-summary>
<el-table-column v-for="(col, index) in tableCol" :key="index" v-bind="col"></el-table-column>
</el-table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.13/index.js"></script>
<script>
const tableCol = [
{ label: '姓名', prop: 'name', minWidth: '186', fixed: 'left' },
{ label: '语文', prop: 'a', minWidth: '186' },
{ label: '数学', prop: 'b', minWidth: '180' },
{ label: '英语', prop: 'c', minWidth: '186' },
{ label: '物理', prop: 'e', minWidth: '186' },
{ label: '化学', prop: 'g', minWidth: '230' },
{ label: '生物', prop: 'h', minWidth: '292' },
{ label: '政治', prop: 'i', minWidth: '230' },
{ label: '历史', prop: 'j', minWidth: '292' },
{ label: '地理', prop: 'k', minWidth: '292' },
{ label: '体育', prop: 'l', minWidth: '292' },
{ label: '品德', prop: 'm', minWidth: '292' },
{ label: '总分', prop: 'sum', minWidth: '292', fixed: 'right' },
{ label: '平均分', prop: 'avg', minWidth: '292', fixed: 'right' }
]
const tableData = [];
const keys = tableCol.map(item => item.prop).slice(1, -2);
for (let i = 0; i < 30; i++) {
const obj = { name: `同学${i + 1}` };
let sum = 0;
keys.forEach(key => {
obj[key] = parseInt(Math.random() * 100);
sum += obj[key];
})
obj.sum = sum;
obj.avg = ((sum * 1.0) / tableCol.length - 3).toFixed(2);
tableData.push(obj)
}
new Vue({
el: '#app',
data() {
return {
tableCol,
tableData
}
},
mounted() {
this.addVirtuallyScroll()
},
methods: {
addVirtuallyScroll() {
this.$nextTick(() => {
const el = this.$refs.accountTable.$el;
if (el.querySelector('#yh-scrollbar-box')) {
el.removeChild(el.querySelector('#yh-scrollbar-box'));
}
const bodyWrapper = this.$refs.accountTable.$refs.bodyWrapper;
const contentWidth = bodyWrapper.querySelector('table').offsetWidth;
const bottom = this.$refs.accountTable.$refs.footerWrapper.offsetHeight;
const scrollbar = document.createElement('div');
scrollbar.setAttribute('id', 'yh-scrollbar-box');
scrollbar.style.bottom = (bottom - 1) + 'px';
const content = document.createElement('div');
content.style.width = contentWidth + 'px';
content.style.height = '10px';
scrollbar.appendChild(content);
scrollbar.addEventListener('scroll', function (e) {
const scrollLeft = e.target.scrollLeft;
const scrollTop = bodyWrapper.scrollTop;
bodyWrapper.scroll(scrollLeft, scrollTop);
})
el.appendChild(scrollbar)
})
}
},
})
</script>
</body>
</html>
效果图如下: