element-ui table固定列错位 踩坑小结

碰到一个奇怪的bug,element-ui table固定列,在切换路由后会错位,

fixed-column.png

为啥会出现错位?不管三七二十一,先审查下元素,看下是哪个元素错位了,

fixed-column1.png

高度高出这么多,估计是被子元素给撑到这么高了,因为高度一般不会写死的,也不会去计算的。 那继续找一下,是哪个子元素搞的鬼,

fixed-column2.png

到这里就不难发现,是这个 body-wrapper 元素的 top 值导致的。那为了验证这个问题,直接在浏览器上把 top 改成 table-header 的高度,发现问题就解决了,

fixed-column3.png

然后覆盖下全局样式,

.el-table__fixed-right {
  .el-table__fixed-body-wrapper {
    top: 44px !important;
  }
}
复制代码

当然这种方式只适合于单行表头且高度固定的,碰到多级表头,可能需要在多级表头的页面再覆盖一次,所以总的来说这种方式不推荐。

为了保险起见,可以用下面这种方式,

doLayout.png

当我切换路由的时候,Table 由显示切换为隐藏,所以调用这个方法可以触发 Table 的重新布局。

那在什么时机调用这个方法呢?既然是对 Table 的重新布局,肯定要先拿到 Table Dom节点,所以可以在 nextTick 里面调用,也就是确保 Table 挂载完成,能拿到实例,才能触发这个方法。

所以可以在获取到数据之后,加上这一段代码,

this.$nextTick(() => {
  this.$refs.tableComponent.doLayout()
})
复制代码

等我加上后,切换路由后发现确实没问题了,以为万事大吉了,没想到等我刷新页面后,打脸了。

刷新页面后,就无法触发这个 nextTick 方法?抱着怀疑的态度,我找到了一篇讲解 nextTick 原理的文章 全面解析Vue.nextTick实现原理。然后尝试把 nextTick 改成了 setTimeout

setTimeout(() => {
  this.$refs.tableComponent.doLayout()
}, 0)
复制代码

然后再刷新页面,可以了。具体原因应该和 Vue 对 nextTick 的降级策略有关。

最后,简单总结下,样式问题,首先审查下元素,看下是哪个元素的哪个属性导致的。定位到问题后,就可以百度或者看github issue或者官方文档了。尽量不要一上来就直接百度,那样可能会失去一次宝贵的学习机会,因为bug的出现可以很好地促进我们主动学习相关知识点,记忆也会更深刻。

猜你喜欢

转载自juejin.im/post/7130165440520650760