antd table 不给宽度时如何设置表头固定

933 阅读2分钟

在中后台管理系统中列表是比较常见的需求,有时我们需要固定表头, 

可以采用监听页面resize事件动态计算表格滚动高度的方式完成,

但有时业务方给的列表并不设置每列的宽度,此时如何解决呢?

通过在列表渲染完成后获取表头和表格体列的宽度,

将大值赋给antd table宽度来保持表头和表格体宽度一致

添加监听事件并限制事件回调的触发频率

this.onResize = throttle(this.addResizeLister, 200)
window.addEventListener('resize', this.onResize)

监听事件

addResizeLister() {
// 这是用了设置表格纵向和横向滚动的对像
 this.scrollMap = undefined // 移除表格的宽度
  this.visibleTableColumns.forEach((item, index) => {
    delete item.width
    this.$set(this.visibleTableColumns, index, item)
  })

// 在表格渲染完成后获取宽度并取列的较大值
  this.$nextTick(() => {
    let tbodyList= []
    const element = this.$refs.tables?.$el?.querySelector('tbody')?.children[0]?.children
    if (!element) {
      return
    }
    for (let i of element) {
      tbodyList.push(i.clientWidth)    }
    let thList = []
    const th = this.$refs.tables.$el.querySelectorAll('th')
    for (let item of th) {
      thList.push(item.clientWidth)
    }
    // 获取表头和表格体对应字段,取大值为宽度
    let list = tbodyList.map((item, index) => {      return Math.max(item, thList[index])
    })
    list.shift() // 我的业务中第一列为复选框,无复选框请移除改行代码    this.computedTableHeight(list) // 将表格宽度传递给计算函数计算表格的滚动高度  })
}

计算横向和纵向滚动并设置表格列宽度

computedTableHeight(list) {
// 获取页面其他元素的高度,用窗口高度减去这些高度并留下一定的空白空间即为表格体的纵向滚动高度
  const navheight = 60 // 上方导航条高度
  const tableheader = 40 // 表格表头
  const pageHeight = 60 // 表格分页高度
  const autoheight = 30 // 自适应预留高度
  const tabheight = 60  // tab页tab高度
  const openToClose = this.$refs.openToClose?.clientHeight || 0
  const header = this.$refs.openToClose?.clientHeight || 0
  const head = this.$refs.head?.clientHeight || 0
  const scollRow = this.$refs.scolllRow?.clientHeight || 0
  let height = window.innerHeight - header - head - scollRow - openToClose - tableheader - pageHeight -autoheight - navheight
  if(document.querySelector('#tabs-box')) {
    height -= tabheight
  }
  // 当没有横向滚动条时,最后一列自适应宽度
  let number = 1
  this.tableHeight = height < 100 ? 100 : height
  // 当要显示横向滚动条并且列的宽度之和大于表格宽度时显示横向滚动条
    const thWidth = list.reduce((accumulator, currentValue) => accumulator + currentValue,0);    const tableWidth = document.querySelector('.ant-table-content').clientWidth;
    // 30 这个值是一个魔法数字, 当用户从少的列加多时有时会出现加了列最后一列显示不全的情况,
    //  加个30像素可以有效避免这种情况,但不是完美解决
    if(thWidth + 30 > tableWidth) {
      this.scrollMap = { x: true}
      number = 0
    }
  const tableBodyHeight = this.$refs.tables?.$el?.querySelector('tbody')?.clientHeight
  if(tableBodyHeight > this.tableHeight) {
    this.visibleTableColumns.forEach((item, index) => {
      if (this.visibleTableColumns.length - 1 - number < index) {
        return
      }
      item.width = list[index] > 300 ? 300 : list[index] + 1
      this.$set(this.visibleTableColumns, index, item)
    })
    if(this.scrollMap) {
      this.scrollMap.y = this.tableHeight
    } else {
      this.scrollMap = {y: this.tableHeight}
    }
  }
},

看一下实现的最终效果