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.viewportHeight
this.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