element-ui 表格组件固定列,data 延迟加载横滚无法拖动的解决方案
前言
最近在 element-ui 的 table 组件又又又又又踩坑了,在 table 设置了 height 的前提下,fixed 固定列在 table-data 延迟加载(很多时候都是异步加载)的时候,固定列下方的横向滚动条拖不动了。
没办法,又要开始源码之路。。。
问题场景描述
代码复现
复现问题首先需要满足以下几个条件:
table设置了height高度table-column中存在fixed固定列table-data延迟加载(或者异步加载),非初始化就存在


页面复现
仔细观察,可以发现:
- 鼠标悬浮在正常列下方的滚动条上时,滚动条颜色变深,处于可以拖动的状态;
- 鼠标悬浮在
fixed固定列下方的滚动条上时,滚动条颜色没变化,滚动条不可拖动; - 选中元素可见,
fixed列元素高度遮挡了滚动条



问题分析
由上图 fixed 固定列元素的样式可知,fixed 固定列元素的高度出现了问题。
具体来讲,即如果存在横向滚动条的情况下,固定列高度应该略低于滚动条的高度,这样才不会影响横向滚动条的使用,如下图:

那么,fixed 固定列的高度是由什么决定的?
源码分析
先看相关代码:
- 固定列的高度的影响样式变量为
fixedHeight fixedHeight的决定因素又是this.layout.viewportHeightthis.layout.viewportHeight的值又取自tableHeight、this.gutterWidth等数据



通过断点等方式,不难发现问题根源:
table初始化时,table-data为空,即this.store.states.data.length为0,故noData也为true,因此viewportHeight的值并没有算上gutterWidth(即滚动条宽度)- 当
table-data延迟获取(异步加载)时,应该更新noData的值,但是table组件并未触发该updateElsHeight方法,故viewportHeight没变,固定列悬浮所以挡住了横向滚动条 - 实际上即便
table-data没加载,一直处于空的状态,横向滚动条在固定列下也是无法拖动的
解决方案
既然问题原因找到了,那么解决方法也很容易就能看出来:
只需要在 table-data 更新的时候,重新去获取一边 noData 的值,从而改变 viewportHeight 的值,就能影响固定列的高度。
直接上代码:
// 在拿到 table 数据后,更新 viewportHeight
this.$nextTick(() => {
const tableHeight = (this.$refs.elTable.layout.tableHeight = this.$refs.elTable.layout.table.$el.clientHeight);
const noData = !(
this.$refs.elTable.layout.store.states.data &&
this.$refs.elTable.layout.store.states.data.length
);
this.$refs.elTable.layout.viewportHeight = this.$refs.elTable.layout
.scrollX
? tableHeight - (noData ? 0 : this.$refs.elTable.layout.gutterWidth)
: tableHeight;
});
修复后的效果

最后
经测试, element-ui 的 2.13.2 和 2.15.3 都是可以如此修复的,故推测大概率其他(比较新的)版本也能按这个思路修复。
那些对 element-ui 进行过二次封装的同学,可以直接在拿到 table-data 时做统一处理。
如果文章对你有帮助,麻烦顺手点个赞。
谢谢!
转载自:https://juejin.cn/post/7243599582943707191