在开发中经常会遇到复杂型表格,多行多列的操作并不可避免,如果是静态数据可以colspan rowspan 跨行写死即可,代表占列、行数,如果是动态数据需要处理对数据做相应的处理。
如图:
合并标段名称,角色名称.....如有更多行亦是如此,直接上代码
<el-table
ref="smallTable"
:data="state.tableData"
:span-method="objectSpanMethod"
class="tableLimit"
max-height="500"
>
<el-table-column align="center" label="标段名称" prop="tenderName" />
<el-table-column align="center" label="角色名称" prop="roleType">
<template #default="{row}">{{ roleTypeList[row.roleType] }}</template>
</el-table-column>
<el-table-column align="center" label="人员名称" prop="userName" />
<el-table-column align="center" label="未签署人员" prop="isSign">
<template #default="{row}">
<i v-if="row.isSign==='00'" class="el-icon-star-off" />
</template>
</el-table-column>
<el-table-column align="center" label="已签署人员" prop="attendStatus">
<template #default="{row}">
<i v-if="row.isSign==='01'" class="el-icon-star-off" />
</template>
</el-table-column>
</el-table>
<script setup>
...引入api
// 数据
const state = reactive({
...
tableData:[],
fieldArr:['tenderName','roleType'], // 需要合并的字段名,按照合并等级来排序
...
})
// 方法
...
const getData = async () =>{
...
const list = await api(params).then(res => {
return res.data.records
})
...
// 数据处理 如果后端返的数据已经排过序了,(这边的排序是指不会出现标段名,roleType混乱情况)
state.tableData = list
// 如果没排序,前端这边处理下 ....
// list.sort((a,b) => {
// if(a.tenderSort === b.tenderSort){
// return Number(a.roleType.slice(-1)) - Number(b.roleType.slice(-1))
// }
// return a.tenderSort - b.tenderSort
// })
this.getSpanArr(state.tableData,state.fieldArr)
}
getSpanArr(data, fieldArr) {
let lastItem = {} // 上一次data的i
fieldArr.forEach((field, ind) => {
data.forEach(i => {
i.mergeCell = fieldArr //存值,把合并字段存入行为了合并单元格时检索列是否含有该字段
const rowSpan = `rowspan_${field}` // 合并的字段出现的次数
// 比较上一次的存值i和该轮i的合并字段,判断是否合并到上个单元格
if (fieldArr.slice(0, ind + 1).every(e => lastItem[e] === i[e])) {
// 如果是,合并行
i[rowSpan] = 0 // 该轮合并字段数量存0
lastItem[rowSpan] += 1 // 上轮合并字段数量+1
} else {
// 初始化进入 && 如果不是,完成一次同类合并,lastItem重新赋值,进入下一次计算
i[rowSpan] = 1 // 该轮合并字段第一次出现 数量存1
lastItem = i // 并且改变比较对象,重新赋值,进行下一次计算
}
})
})
},
// 合并列
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
// 判断当前单元格是否需要合并
// 之前将每个row存入合并字段数组mergeCell,同时column列对象有property属性,即为el-table-column的prop属性
if (row.mergeCell.includes(column.property)) {
const rowspan = row[`rowspan_${column.property}`]
if (rowspan) { // 如果有则把row的字段合并数量存入rowspan colspan存1
return { rowspan, colspan: 1 }
} else { // 如果没有,则置0
return { rowspan: 0, colspan: 0 }
}
}
},
</script>
代码注释写的很清楚,应该看一下就明白了,这边只写了多行多列合并,如果需要同时合并多行多列方法一样,主旨就是比较待合并字段,比较这次和上次是否一样,不是则,新索引的数量存1,如果是则老索引的数量+1,新索引的数量存0,不管是之前单列合并行的标志位pos 还是这种存i方式,都可以,记录一下。