9

解决 Antd 3 表格固定列在 Modal 模态框下显示异常的问题

 3 years ago
source link: https://paugram.com/coding/fix-antd-3-table-fixed-column-bug.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

解决 Antd 3 表格固定列在 Modal 模态框下显示异常的问题

2021.07.12进击的码农 0 48

公司某个项目主要采用 Antd 3 作为 UI 组件库,Antd 确实能解决大多数的业务需求,但在某个页面下出现了表格布局错乱异常,展现出了未对齐的「破碎」效果,如图所示:

Antd-3-Table-Bug.jpg

真是个奇怪的问题 🤔,我看了下,因为右侧固定列的高度是通过 JS 计算出来的。这么做的原因估计是为了避开 position: sticky 兼容性太低的坑,所以才这么做的。

具体的复现代码,可以参考我在 CodeSandbox 上的 案例

一般依赖问题都是升级解决,我也尝试过升级 Antd 到 4,结果发现有很多组件都修改了,此前该项目里的样式覆盖全部失效。升级 React 解决掉「项目依赖」还只是冰山一角,如此多的 CSS 差异在短时间内很难完全排查透彻并进行调整!

那就只能回到项目本身思考了。当时写过一个小 Demo,想了许久都没分析出原因。从表格渲染的数据本身,再到表格内容样式的修改,都没成功复现。我一直在怀疑是不是这个高度的算法问题,然而这个表格并不是 Antd 自己的实现,而是基于 rc-table 这个通用组件库实现,修改源码并不实际。

当时还有其他更重要的事情需要解决,因此这个问题被耽搁许久。


时至今日,我突然想到了一个可能触发此 Bug 的原因,就是 Antd 的模态框出现动画。试了试,确实有了新的发现!所以说有些事情确实不能急,不急的时候真就得来全不费工夫。

Antd 3 的模态框默认采用了一个缩放弹出的动画,我把此前的 Demo 修改成「模态框」内显示之后,也并没有出现上述效果。但如果当它变成了异步获取呢...

想要模拟一个异步,最简单的办法就是在 setTimeout 函数里面执行 State 刷新。当我把时间改成 100 毫秒之后,Bug 成功被我复现了!不快不慢,恰好是一个在动画「没播放结束」又「开始了许久」的情况下,和平时调服务器数据的时间差不多。

setTimeout(() => {
  setData(listData);
}, 100);

按照我上面的猜测,强行把 Antd 的缩放动画在开发工具里覆盖掉,再打开模态框,确实没有出现显示异常的情况了。

CSS3 的缩放动画会让元素变小,元素变小的情况下去计算表格高度,就有可能拿到的是在「动画未结束」播放状态下的高度。再加上异步修改数据会造成表格重绘,改变高度。我猜大概率是因为「异步处理」导致两者恰好踩着点一起执行了。

既然已经分析出原因了,那最简单的办法就是用 CSS 把内置的动画直接用 animation: none !important 进行覆盖。但是这样做就会在 300ms 以内的动画预留时长下显示为空,严重影响用户操作体验。

一番搜索之后,Antd 文档里面有一句特别不起眼的问题说明,叫“如何关闭 Modal 动画?”

你可以通过 transitionName=""maskTransitionName="" 去除动画 CSS,但是需要注意的是。该方法为内部方法,我们不保证下个大版本重构时该属性会被保留。

这两个属性名称并没有在文档的其他位置出现,可以看出这并不是蚂蚁那边想让用户修改的东西。但不可否认的是,Antd 3 的源码里面确实有接受这个参数。

那么,这些动画都允许接受什么值呢?我在 Antd 的源码里搜索到了答案。就是在 antd/es/style/core/motion 这个目录里面,存放着各种用于展示的过渡动画。

亲测可以使用的有 fademove-up,这两个动画分别是渐变和平移,都不会改变元素的大小,没有出现本文所述的 Bug 症状。

<Modal transitionName="move-up" title="About Paul" visible={visible}>

Antd 4 的表格已经换成了 sticky,因此使用 Antd 4 的项目都没有这个问题。考虑到现在 Antd 3 不维护了,于是这个问题就不去 Issues 里面凑热闹了。相信能搜到这里来的,都是接盘侠了吧,哈哈哈 😂


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK