我最近在写一个自适应列宽的需求,el-tabl可以e自适应的表格宽度,仅仅是对于100%的效果来说,对于有多列数据,想实现可以展示足够宽的数据列,并且可以有横向滑动条,这样使得每一列都能有足够宽度展示数据。
根据网上找到的几个解决方案,都是计算宽度实现的,这里我也是用的这种方式,但是由于数据有些地方缺失,还有一些地方的数据为string,里面带”\n",所以根据项目情况,我优化了这个计算宽度的函数,这里作为记录。
效果图如下:
<el-table
fit
v-if="tableData"
style="width: 100%; overflow-x: auto"
v-loading="tableLoading"
:height="`calc(100vh - 150px)`"
:data="tableData" //表格数据
border
ref="rightTable"
:header-cell-style="tableHeadClass" //表头加了一个背景色
>
<el-table-column label="序号" type="index" :index="getIndex" width="80"></el-table-column>
//序号列一定加固定宽度,要不然列一多就会挤到序号列
<el-table-column
v-for="(col, index) in tableCol" //表格结构
:key="index"
:label="col.colName"
:prop="col.colId"
:width="flexColumnWidth(col.colId, tableData)" //这里是计算宽度的函数
>
<template #default="scope">
<span style="white-space: pre-wrap">{{ scope.row[col.colId] }}</span>
</template>
</el-table-column>
</el-table>
由于后端经常是将结构和数据分开返回的,所以这里的tableCol,与tableData,都循环了一下。
我这里,tableData的结构是对象数组型的,所以比较好遍历。
下面是计算宽度的函数(可以直接复制,修改传参就行,记得将tableData改为自己的数据)
//自适应宽度
flexColumnWidth(str, tableData, flag = 'max') {
// str为该列的字段名(传字符串);tableData为该表格的数据源(传变量);
// flag为可选值,可不传该参数,传参时可选'max'或'equal',默认为'max'
// flag为'max'则设置列宽适配该列中最长的内容,flag为'equal'则设置列宽适配该列中第一行内容的长度。
str = str + ''
let columnContent = ''
if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) {
return
}
if (!str || !str.length || str.length === 0 || str === undefined) {
return
}
if (flag === 'equal') {
// 获取该列中第一个不为空的数据(内容)
for (let i = 0; i < tableData.length; i++) {
if (tableData[i][str].length > 0) {
// console.log('该列数据[0]:', tableData[0][str])
columnContent = tableData[i][str]
break
}
}
} else {
// 获取该列中最长的数据(内容)
let index = 0
for (let i = 0; i < tableData.length; i++) {
//当数据不为空的时候比较,为空自动下一个
if (tableData[i][str] !== null) {
let now_temp = tableData[i][str] + ''
let max_temp = tableData[index][str] + ''
if (now_temp.length > max_temp.length) {
index = i
}
}
}
columnContent = tableData[index][str]
}
//分行后的数据选择最长的一行分配宽度
if (columnContent && columnContent.length >= 15) {
let content = JSON.parse(JSON.stringify(columnContent)) //深拷贝
let kIndex = 0
for (let k = 0; k < content.split('\n').length; k++) {
const kNow = content.split('\n')[k]
const KMax = content.split('\n')[kIndex]
if (kNow.length > KMax.length) {
kIndex = k
}
}
columnContent = content.split('\n')[kIndex]
// 以下分配的单位长度可根据实际需求进行调整
let flexWidth = 0
for (let i = 0; i < columnContent.length; i++) {
let char = columnContent[i]
if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
// 如果是英文字符,为字符分配8个单位宽度
flexWidth += 8
} else if (char >= '\u4e00' && char <= '\u9fa5') {
// 如果是中文字符,为字符分配15个单位宽度
flexWidth += 16
} else {
// 其他种类字符,为字符分配8个单位宽度
flexWidth += 4
}
}
if (flexWidth < 80) {
// 设置最小宽度
flexWidth = 120
}
if (flexWidth > 250) {
// 设置最大宽度
flexWidth = 450
}
// console.log('该列数据[i]:', columnContent, '宽度:', flexWidth + 'px')
return flexWidth + 'px'
} else {
return 'auto'
}
},
这里也提供了一个修改表头颜色的函数,如下:
tableHeadClass({ rowIndex, columnIndex }) {
if (rowIndex === 0) {
return { background: '#2969ad', color: 'white' }
} else {
return { background: '#ededed' }
}
},
以上就是我在开发表格自适应宽度。