注意:const fields =
是要合并的字段
一、vxe-table合并行数据
1.代码
<vxe-table
border
resizable
height="500"
:scroll-y="{enabled: false}"
:span-method="mergeRowMethod"
:data="tableData3"
>
<vxe-column type="seq" width="60" />
<vxe-column field="key" title="设备名称" />
<vxe-column field="num" title="Num" />
<vxe-column field="content" title="Translate" />
<vxe-column field="language" title="Language">
<template v-slot="{ row }">
<div @click="getRow(row)">{{ row.language }}</div>
</template>
</vxe-column>
<vxe-column field="key" title="操作">
<template v-slot="{ row }">
<div @click="getRow(row)">获取数据</div>
</template>
</vxe-column>
</vxe-table>
tableData3: []
getDataList2() {
this.tableData3 = [
{ id: 10001, key: 'app.label.name', num: 1, content: '名称', language: '1' },
{ id: 10002, key: 'app.label.name', num: 1, content: 'Name', language: '2' },
{ id: 10003, key: 'app.label.name', num: 1, content: '性别', language: '3' },
{ id: 10004, key: 'app.label.name', num: 1, content: 'Sex', language: '4' },
{ id: 10005, key: 'app.label.age', num: 3, content: '年龄', language: '5' },
{ id: 10006, key: 'app.label.age', num: 3, content: 'Age', language: '6' },
{ id: 10007, key: 'app.label.role', num: 4, content: '角色', language: '7' },
{ id: 10008, key: 'app.label.role', num: 4, content: 'Role', language: '8' },
{ id: 10009, key: 'app.label.address', num: 5, content: '地址', language: '9' },
{ id: 10010, key: 'app.label.address', num: 5, content: 'Address', language: '10' },
{ id: 10011, key: 'app.label.nickname', num: 6, content: '昵称', language: '11' },
{ id: 10012, key: 'app.label.nickname', num: 6, content: 'Nickname', language: '12' }
]
},
// 通用行合并函数(将相同多列数据合并为一行)
mergeRowMethod({ row, _rowIndex, column, visibleData }) {
console.log(row, _rowIndex, column, visibleData)
const fields = ['key', 'num']
const cellValue = row[column.field]
if (cellValue && fields.includes(column.field)) {
const prevRow = visibleData[_rowIndex - 1]
let nextRow = visibleData[_rowIndex + 1]
if (prevRow && prevRow[column.field] === cellValue) {
return { rowspan: 0, colspan: 0 }
} else {
let countRowspan = 1
while (nextRow && nextRow[column.field] === cellValue) {
nextRow = visibleData[++countRowspan + _rowIndex]
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 }
}
}
}
},
getRow(row) {
console.log(row)
},
二、使用element-plus的el-table动态合并行
参考了vxe-table的处理返参方式得到的
2.代码
<template>
<div>
<pre>{{ tableData }}</pre>
<div>手动合并</div>
<el-table :data="tableData" :span-method="arraySpanMethod" border style="width: 100%">
<el-table-column prop="id" label="ID" width="180" />
<el-table-column prop="name" label="Name" />
<el-table-column prop="amount1" sortable label="Amount 1" />
<el-table-column prop="amount2" sortable label="Amount 2" />
<el-table-column prop="amount3" sortable label="Amount 3" />
</el-table>
<div style="margin-top: 100px;">通过计算 动态合并相同行</div>
<el-table :data="tableData" :span-method="objectSpanMethod" border style="width: 100%; margin-top: 0px">
<el-table-column prop="id" label="ID" width="180" />
<el-table-column prop="name" label="Name" />
<el-table-column prop="amount1" label="Amount 1" />
<el-table-column prop="amount2" label="Amount 2" />
<el-table-column prop="amount3" label="Amount 3" />
</el-table>
</div>
</template>
<script lang="ts" setup>
import type { TableColumnCtx } from 'element-plus'
interface User {
id: string
name: string
amount1: string
amount2: string
amount3: number
}
interface SpanMethodProps {
row: User
column: TableColumnCtx<User>
rowIndex: number
columnIndex: number
}
const arraySpanMethod = ({
row,
column,
rowIndex,
columnIndex,
}: SpanMethodProps) => {
if (rowIndex % 2 === 0) {
if (columnIndex === 0) {
return [1, 2]
} else if (columnIndex === 1) {
return [0, 0]
}
}
}
const objectSpanMethod = ({
row,
column,
rowIndex,
columnIndex,
}: SpanMethodProps) => {
console.log(row,
column,
rowIndex,
columnIndex,);
// if (columnIndex === 0) {
// if (rowIndex % 2 === 0) {
// return {
// rowspan: 2,
// colspan: 1,
// }
// } else {
// return {
// rowspan: 0,
// colspan: 0,
// }
// }
// }
const fields = ['id', 'name']
const cellValue = row[column.property]
if (cellValue && fields.includes(column.property)) {
const prevRow = tableData[rowIndex - 1]
let nextRow = tableData[rowIndex + 1]
if (prevRow && prevRow[column.property] === cellValue) {
return { rowspan: 0, colspan: 0 }
} else {
let countRowspan = 1
while (nextRow && nextRow[column.property] === cellValue) {
nextRow = tableData[++countRowspan + rowIndex]
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 }
}
}
}
}
const tableData: User[] = [
{
id: '11111',
name: 'Tom',
amount1: '234',
amount2: '3.2',
amount3: 10,
},
{
id: '11111',
name: 'Tom',
amount1: '165',
amount2: '4.43',
amount3: 12,
},
{
id: '12987124',
name: 'Tom',
amount1: '324',
amount2: '1.9',
amount3: 9,
},
{
id: '12987125',
name: 'Jack',
amount1: '621',
amount2: '2.2',
amount3: 17,
},
{
id: '12987126',
name: 'Jack',
amount1: '539',
amount2: '4.1',
amount3: 15,
},
]
</script>