网上搜索的解决方案大都没什么卵用。这里用的vue自定义指令去解决,思路是隐藏自带的滚动条,增加一个自定义滚动条。
我们在指令文件夹directive下新建一个elTableScrollFixed.js文件存放自定义指令代码如下:
// 自定义滚动条方法
function setCustomScrolling(el,tableNode,summaryNode) {
el.classList.add('custom-scrolling') // 追加一个自定义类,通过这个类在CSS中隐藏原先的滚动条.custom-scrolling .el-table__body-wrapper::-webkit-scrollbar{display: none}
let bodyWidth = tableNode.offsetWidth + 'px' // 表格宽度
let tableWidth = tableNode.querySelector('table').offsetWidth + 'px' // 表格内容宽度
let sunmmaryHeight = summaryNode.offsetHeight?summaryNode.offsetHeight + 'px' : '37px' // 表尾合计行高度
let removeVirtualNodes = el.querySelectorAll('.virtual-scrolling-box') // 防止重复插入,把已有的虚拟滚动条节点删除掉
// 遍历这些节点并删除
if(removeVirtualNodes.length>0){
removeVirtualNodes.forEach((node)=> {
if (node.parentNode) {
node.parentNode.removeChild(node);
}
})
}
// 追加虚拟滚动条节点
el.insertAdjacentHTML('beforeend',`<div class="virtual-scrolling-box" style="width: ${bodyWidth};height: 8px;overflow-x: auto;overflow-y: hidden;position: absolute;bottom: ${sunmmaryHeight};left: 0;z-index: 5">
<p style="width: ${tableWidth};height: 8px;"></p>
</div>`
)
let virtualScrollingBox = el.querySelector('.virtual-scrolling-box') // 获取追加的虚拟滚动条节点
// 监听虚拟滚动条滚动
el._virtualScrollingBox_ = virtualScrollingBox
el._virtualScrollingEvent_ = []
virtualScrollingBox.addEventListener('scroll', function virtualScrolling() {
el._virtualScrollingEvent_.push(virtualScrolling) // 事件追加进去解绑时候销毁
let scrollLeft = virtualScrollingBox.scrollLeft;
tableNode.scrollLeft = scrollLeft // 滚动距离赋给表格节点
})
}
export default {
bind(el, binding, vnode){
vnode.context.$nextTick(() => {
let tableNode = el.querySelector('.el-table__body-wrapper.is-scrolling-left') // 表格节点
let summaryNode = el.querySelector('.el-table__footer-wrapper') // 合计行节点
// tableNode && summaryNode 成立则认为是有滚动条且有合计行
if(tableNode && summaryNode){
setCustomScrolling(el,tableNode,summaryNode) // 设置自定义滚动条
// 监听元素变化
const resizeObserver = new ResizeObserver((entries) => {
tableNode = el.querySelector('.custom-scrolling .el-table__body-wrapper') // 重新获取表格节点
setCustomScrolling(el,tableNode,summaryNode) // 设置自定义滚动条
});
resizeObserver.observe(el)
// 赋值给el用做销毁
el._resizeObserver_ = resizeObserver;
}
})
},
componentUpdated(el, binding, vnode){
vnode.context.$nextTick(() => {
vnode.context.$refs['table'].doLayout() // 调用组件上的方法
});
},
unbind(el, binding, vnode){
// 销毁元素监听
if (el._resizeObserver_) {
el._resizeObserver_.disconnect()
delete el._resizeObserver_
}
// 移除滚动条上的监听事件
if(el._virtualScrollingEvent_ && el._virtualScrollingEvent_.length>0){
el._virtualScrollingEvent_.forEach(item=>{
el._virtualScrollingBox_.removeEventListener('scroll', item);
})
}
}
}
PS:尾部合计行高度37px以及滚动条的8px按自己需求更改。
隐藏自身滚动条
在全局css文件中增加如下样式,隐藏el-table自带的滚动条
.custom-scrolling{
.el-table__body-wrapper::-webkit-scrollbar{display: none}
}
注册指令
在main.js中注册全局指令
import elTableScrollFixed from '@/directive/elTableScrollFixed.js'
Vue.directive('elTableScrollFixed', elTableScrollFixed)
使用指令
在el-table上使用自定义指令
<el-table v-el-table-scroll-fixed >...</el-table>
效果如下

本文介绍了如何使用Vue的自定义指令解决el-table的滚动条问题,通过隐藏默认滚动条并添加自定义滚动条,配合resizeObserver监听元素变化,实现在表格有滚动需求时动态显示滚动条。
3490






