由于table组件本身并不支持宽度自适应,但实际项目需要,而且多处有用到table组件,所以尝试着自己来二次封装一下组件
刚开始的想法很简单,就是获取每一列中数据和标题在表格中的长度,然后将当中最大的长度作为该列的宽度就可以了。
但是我们怎么才能知道它们在表格中的长度呢?
打开F12查看表格中的数据,我们可以发现,数据的外面包了一层span标签,而且父元素设置了padding

那我就在想,能不能自己手动创建一个span标签包裹数据,然后通过offerWidth获取宽度呢?
说干就干!
// calculateColumnWidth.js文件
const getTextWidth = str => {
const span = document.createElement('span')
span.style.display = 'inline-block'
span.style.visibility = 'hidden'
span.style.fontSize = '14px'
span.innerText = str
document.body.appendChild(span)
const width = span.offsetWidth
document.body.removeChild(span)
return width + 36 + 15
}
export const calculateColumnWidth = (columns, data) => {
columns.forEach(c => {
if (c.type === 'selection') return
const arr = data.map(d => d[c.key])
arr.push(c.title)
// 比较某一列的所有值(包含标题名)
c.width = Math.max(...arr.map(d => getTextWidth(d)))
})
}
这里的getTextWidth函数是用来计算每个数据应有的宽度(加36是因为标签的父元素默认设置了左,右padding为18px,而这里加15是想数据不要占满整个表格,左右留有一定的空间。值得注意的是,如果没有修改table中的默认字体大小,则字体大小要保持一致)
而calculateColumnWidth函数是用来计算并设置每列的最大宽度的

尝试引入函数并使用watch来深度监听传入的data数据,如果数据有变,就会调用calculateColumnWidth函数,从而更新columns这个数组对象中的宽度。由于这个table组件如果不传data,也会展示表格(如下图),所以immediate需要设置为true,让calculateColumnWidth函数在页面一加载就执行一次

最终实现宽度自适应的效果,如下图:
无数据时:

有数据时:

二次封装table组件的源代码:
父组件中使用(使用widthAuto来控制是否要宽度自适应):
