vue.js el-table 动态单元格列合并
一、业务需求:
一个展示列表,表格中有一部分列是根据后端接口动态展示,对于不同类型的数据展示效果不一样。如果接口返回数据是’类型1‘的,则正常展示,如果是’类型2‘的数据,则合并当前数据的动态表格。
二、实现思路:
1、先将普通表格实现,不考虑合并效果;
2、在表格上对要合并的单元格类型进行区分;
3、 在表格上使用:span-method="arraySpanMethod"方法触发表格;
4、在arraySpanMethod方法内接收数据处理合并,确定从哪一列开始合并到哪一列合并结束;
三、代码展示:
<el-table
ref="table"
size="mini"
height="100%"
:data="tableData"
:span-method="arraySpanMethod"
:header-cell-style="{
background: '#f5f7fa',
fontWeight: 'bold',
color: '#303133'
}"
border
>
<el-table-column
type="index"
header-align="center"
align="center"
label="序号"
width="50"
></el-table-column>
<el-table-column
width="120"
prop="indexShowName"
label="名称"
show-overflow-tooltip
></el-table-column>
<el-table-column
width="80"
prop="type"
label="类型种类"
show-overflow-tooltip
>
<template slot-scope="scope">
{{ scope.row.type === '1' ? '类型1' : '类型2' }}
</template>
</el-table-column>
<el-table-column
v-for="(item, index) in tableColumns"
:key="index"
width="80"
:label="item.year"
show-overflow-tooltip
>
<template slot-scope="scope">
<!-- 类型1展示name -->
<div
v-if="scope.row.type === '1'"
style="text-align: center"
>
{{
scope.row.uploadValueList[index]?.uploadValueName
}}
</div>
<!-- 类型2展示value -->
<div v-else>
{{ scope.row.uploadValueList[index].uploadValue }}
</div>
</template>
</el-table-column>
<el-table-column
width="160"
prop="reportDate"
label="上报时间"
show-overflow-tooltip
></el-table-column>
<el-table-column
width="195"
label="操作"
header-align="center"
align="center"
fixed="right"
>
<template slot-scope="scope">
<el-button
size="small"
style="color: #409eff; padding: 0"
type="text"
@click="detailClick(scope.row)"
>数据明细</el-button
>
</template>
</el-table-column>
</el-table>
// --------------methods方法--------------------
// 右侧表格
initTable() {
const params = {
pageNum: this.pages.pageIndex,
pageSize: this.pages.pageSize,
}
this.tableLoading = true
//api接口调用xxx
xxx(params)
.then((res) => {
if (res.code === 200) {
const { total } = res.result
// const { records, total } = res.result
//后端接口数据返回形式如下:
const records = [
{
indexShowName: '测试001',
type: '1',
reportDate: '2023-12-01 15:53:46',
uploadValueList: [
{
id: '1',
year: '2021年',
uploadValue: '0',
uploadValueName: '完全符合'
},
{
id: '2',
year: '2022年',
uploadValue: '0',
uploadValueName: '完全符合'
},
{
id: '3',
year: '2023年',
uploadValue: '0',
uploadValueName: '完全符合'
},
{
id: '4',
year: '2024年',
uploadValue: '0',
uploadValueName: '完全符合'
}
]
},
{
indexShowName: '测试002',
type: '2',
reportDate: '2023-12-01 13:45:53',
uploadValueList: [
{
id: '5',
year: '2021年',
uploadValue: '99.00'
},
{
id: '6',
year: '2022年',
uploadValue: '98.00'
},
{
id: '7',
year: '2023年',
uploadValue: '77.00'
},
{
id: '8',
year: '2024年',
uploadValue: '34.00'
}
]
}
]
if (records && records.length > 0) {
// 使用第一个元素的 uploadValueList 来创建列
this.tableColumns = records[0].uploadValueList.map((item) => ({
year: item.year, // 使用 year 作为列的标签
id: item.id // 用于做key
}))
}
this.tableData = records
this.pages.total = total
} else {
this.$message.error(res.message)
}
})
.finally(() => {
this.tableLoading = false
})
},
// 单元格合并 {当前行row、当前列column、当前行号rowIndex、当前列号columnIndex}
arraySpanMethod({ row, column, rowIndex, columnIndex }) {
// 类型1,且动态数据长度>1
if (row.type === '1' && row?.uploadValueList?.length > 1) {
const len = row?.uploadValueList?.length
// 合并从下标为0开始的【下标为3的第四列,动态数据长度】
if ( columnIndex > 2 && columnIndex <= 2 + Number(len) ) {
return {
rowspan: 1,
colspan: columnIndex === 3 ? len : 0
}
}
}
},