ElementUI中表格表头高度改变导致的固定列塌陷问题

402 阅读3分钟

我用的ElementUI版本号是2.13.2,后面的版本不知道这个问题解决了没有,如果解决了的话麻烦在评论里提醒一下作者。

问题的起因是接手一个项目,然后在到处点点的情况下,突然发现固定列的高度不太对。

然后仔细分析了一下发现,当移动表头时,如果表头的高度发生了变化,固定列并不会在这一次渲染中更新高度变化,而是在下一次渲染中更新高度变化,这就引起了我的好奇。

当然,分析问题先要找对方向,所以我打开了Element官方文档,在2.13.2版本的文档中试了一下,发现文档中的演示项目并不会发生固定列塌陷问题,所以我判断应该是本地代码的问题

但是我把本地代码看了个遍,也没发现哪一段导致了这个问题,所以只能用笨方法,代码逐行替换来找到问题所在。

最后我终于找到了,导致这个问题的罪魁祸首就是el-table标签的height属性和max-height属性

我多次测试下的结果表明

当给el-table赋值了height属性时,表头的高度不管如何变化都会造成固定列塌陷问题

当给el-table赋值了max-height属性时,表头的高度在升高的时候才会造成固定列塌陷问题

当不给el-table赋值这两个属性时,表头的高度如何变化都不会造成固定列塌陷问题

所以,推荐大家尽量不要给el-table赋值height属性,防止固定列塌陷。

如果你希望table有纵向滚动条,而不得不使用height属性的话,那我推荐给el-table加上header-dragend这个方法

PS:如果偷懒可以使用max-height属性,这个属性在表头降低高度的时候不会造成固定列塌陷问题,配合header-dragend方法能够完美处理,不需要控制初始值低于最低宽度

PS2:下面这个方法的是按照中文来写的,如果不是中文或者有切换语言的需求的话,一开始的算式需要改一下,后面的存储对象结构也需要加一层语言层

<el-table @header-dragend="handleHeaderDragend">
  methods: {
    handleHeaderDragend(newWidth, oldWidth, column, event) {
      // 计算出表头的最低宽度,其中14是font-size的值,24是padding(10) *2 加上误差4
      const mixWidth = column.label.length * 14 + 24
      // 声明真实宽度
      let realWidth
      // 判断,如果最低宽度大于新的宽度,就把最低宽度赋值给真实宽度,反之就把新的宽度赋值给真实宽度
      if (mixWidth > newWidth) realWidth = mixWidth
      else realWidth = newWidth
      // 给表头宽度赋值
      column.width = realWidth
      // 上面就是防止表头宽度过低导致表头高度异常的代码,下面是记录表头改变的代码
      // 取本地存储的表格宽度对象,如果没有或者不是对象就创建一个空对象
      let obj
      try {
        const data = JSON.parse(localStorage.getItem('tableHeaderWidth'))
        if (Object.prototype.toString.call(data) === '[object Object]') obj = data
        else obj = {}
      } catch (error) {
        obj = {}
      }
      // 这里我是按Vue项目写的如果不是Vue项目可以直接拿window.location.hash.split('#/')[1]替换this.$route.fullPath来取路径作为唯一的key值
      const path = this.$route.fullPath || window.location.hash.split('#/')[1]
      // 判断路径是否已存有数据,如果没有就创建一个空对象
      if (Object.prototype.toString.call(obj[path]) !== '[object Object]') obj[path] = {}
      // 把表头宽度赋值给对象
      obj[path][column.property] = realWidth
      // 将对象保存到本地
      localStorage.setItem('tableHeaderWidth', JSON.stringify(obj))
    },
  },

最后问个问题,codepen里面怎么调用Vue啊?我本来想给ElementUI提个issue的,但是github需要示例,我想从ElementUI的官方文档里弄一个,然后发现官方文档里跳转的codepen代码跑不动,报了一个Vue是未定义的错误。