这里提供两种方法,选择适合你的业务场景使用
第一种
- 效果图
- 前端页面简单代码
<el-table
v-loading="loading"
border
:span-method="arraySpanMethod"
:data="tableData">
<el-table-column
prop="projectVo.projectName"
label="项目名称">
</el-table-column>
<el-table-column
prop="taskTitle"
label="任务名称">
</el-table-column>
</el-table>
- js处理数据的方法
// 获取列表数据
loadSubProject () {
this.loading = true
this.parentProjectName = this.$officeCacheUtils.getOfficeName(this.queryParam.executiveDepartmentId, '-')
this.queryParam.insideParentId = this.projectId
this.$http({
url: '/project/project/selectProjectTask',
method: 'get',
params: {
...this.queryParam
}
}).then(({ data }) => {
if (data && data.success) {
this.tableData = data.list
this.mergeProject(data.list)
this.loading = false
}
})
},
// 合并单元格
mergeProject (arr) {
this.spanObj = []
var obj = {}
var k = ''
let len = arr.length
for (let i = 0; i < len; i++) {
// 根据指定列合并
k = arr[ i ].projectVo.projectName
if (obj[ k ]) {
obj[ k ] ++
} else {
obj[ k ] = 1
}
}
for (let o in obj) {
for (let i = 0; i < obj[ o ]; i++) {
if (i === 0) {
this.spanObj.push(obj[ o ])
} else {
this.spanObj.push(0)
}
}
}
},
// 合并单元格
arraySpanMethod ({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
let _row = this.spanObj[ rowIndex ]
let _col = this.spanObj[ rowIndex ] > 0 ? 1 : 0
return {
rowspan: _row,
colspan: _col
}
}
},
第二种(可以灵活配置)
-
参考博客 https://blog.csdn.net/qq_42309277/article/details/120532098
-
完整代码地址(感谢博主提供) https://github.com/lolStoneLee/mergeTable.git
-
效果图
-
实现思路 通过倒序遍历数组,符合条件时使用combineProp进行累加,并设置当前单元格属性rowspan和colspan为0,直到不符合条件后对当前项rowspan进行赋值
-
前端简单页面
<el-table
:data="dataList"
:span-method="arraySpanMethod"
border
style="width: 100%">
<template v-for="(item, index) in colDataList">
<el-table-column
:label="item.label"
:prop="item.prop"
></el-table-column>
</template>
<!-- 增减项 -->
<el-table-column label="操作">
<template v-slot="scope">
<i class="icons el-icon-circle-plus-outline"
@click="addRow(scope.row, scope.$index)"></i>
<i class="icons el-icon-remove-outline"
@click="delRow(scope.$index)"></i>
</template>
</el-table-column>
</el-table>
- js方法
methods : {
refreshList () {
this.loading = true
this.$http({
url: '/task/taskInfo/correntionScore',
method: 'get',
params: {
'pageNo': this.pageNo,
'pageSize': this.pageSize,
'orderBy': this.orderBy,
...this.searchForm
}
}).then(({ data }) => {
if (data && data.success) {
this.dataList = data.page.list
// 调用合并的方法
this.mergeData(this.dataList)
this.total = data.page.count
this.loading = false
}
})
},
isEmpty ( val ) {
return typeof val == 'undefined' || val === null || val == '-'
} ,
isObject ( val ) {
return Object.prototype.toString.call ( val ) === '[object Object]'
} ,
arraySpanMethod ( { row , column , rowIndex , columnIndex } ) {
const span = column[ 'property' ] + '-span'
if ( row[ span ] ) {
return row[ span ]
}
} ,
mergeData ( list ) {
// mergeTarge - 合并项依据
// combineProp - 根据mergeTarge 进行合并的单元格属性
let config = {
mergeTarget : 'id' , // 通用依据
combineProp : [
'id' ,
'name' ,
{
mergeTarget : 'name' ,
combineProp : ['amount1' , 'amount2']
} ,
'amount3'
]
}
return this.filterData ( config , [].concat ( list ) )
} ,
filterData ( config , dataList , targetProp ) {
const { mergeTarget , combineProp } = config
// 叠加的合并条件
combineProp.forEach ( ( column , index ) => {
// 记录合并项
let combineCount = 1
if ( this.isObject ( column ) ) {
return this.filterData.call ( this , column , dataList , mergeTarget )
}
// 使用倒序遍历
for ( let i = dataList.length - 1 ; i >= 0 ; i -- ) {
let curr = dataList[ i ] ,
prev = dataList[ i - 1 ]
if ( this.isEmpty ( prev ) ) {
// 已经循环完毕
curr[ `${ column }-span` ] = {
rowspan : combineCount ,
colspan : combineCount >= 1?1:0
}
break;
}
if ( ( prev[ targetProp ] === curr[ targetProp ] &&
prev[ mergeTarget ] === curr[ mergeTarget ] ) &&
prev[ `${ column }` ] === curr[ `${ column }` ]
) {
++ combineCount;
curr[ `${ column }-span` ] = {
rowspan : 0 ,
colspan : 0
}
} else {
curr[ `${ column }-span` ] = {
rowspan : combineCount ,
colspan : combineCount >= 1?1:0
}
prev[ `${ column }-span` ] = {
rowspan : 1 ,
colspan : 1 ,
}
// 前后项不相符时,对combinecount进行重置
combineCount = 1
}
}
} )
return dataList
} ,
} ,
computed : {
colDataList () {
return [{
label : 'ID' ,
prop : 'id'
} , {
label : '姓名' ,
prop : 'name'
} , {
label : '数值1' ,
prop : 'amount1'
} , {
label : '数值2' ,
prop : 'amount2'
} , {
label : '数值3' ,
prop : 'amount3'
}]
}
}