vue2+vue3 Table表格合并
之前在写表格合并的时候非常痛苦,弄不明白合并的具体逻辑,我这里直接贴上通用方法,只需要配置合并规则就可以了,在这里不扯那么多过程,你完全可以拷贝回去立马能用。
vue2 表格合并
<el-table
:data="tableData"
:span-method="(param)=>objectSpanMethod(param,tableData)"
border
style="width: 100%">
<el-table-column
prop="id"
label="ID"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名">
</el-table-column>
<el-table-column
prop="amount1"
sortable
label="数值 1">
</el-table-column>
<el-table-column
prop="amount2"
sortable
label="数值 2">
</el-table-column>
<el-table-column
prop="amount3"
sortable
label="数值 3">
</el-table-column>
</el-table>
<script>
function filterArray(item) {
const valueArray = this.rule.filter(prop => {
return item[prop] === this.data[prop]
})
if (valueArray.length === this.rule.length) {
return true
} else {
return false
}
}
export default {
data() {
return {
tableData: [{
id: '12987122',
name: '王小虎',
amount1: '234',
amount2: '3.2',
amount3: 10
}, {
id: '12987123',
name: '王小虎',
amount1: '165',
amount2: '4.43',
amount3: 12
}, {
id: '12987124',
name: '王小虎',
amount1: '324',
amount2: '1.9',
amount3: 9
}, {
id: '12987125',
name: '王小虎',
amount1: '621',
amount2: '2.2',
amount3: 17
}, {
id: '12987126',
name: '王小虎',
amount1: '539',
amount2: '4.1',
amount3: 15
}],
spanRule: {
rule: {
0: ['department_name'] //表示第一列的合并规则
}
}
};
},
methods: {
// 表格合并
objectSpanMethod({ row, column, rowIndex, columnIndex }, item) {
if (Object.keys(this.spanRule.rule).includes(columnIndex.toString())) {
// filter验证数组
const currentTable = {
rule: this.spanRule.rule[columnIndex],
data: item[rowIndex]
}
// 该单元格是否被合并 true 合并, false : 不合并
let chooseSpan = false
if (rowIndex !== 0) {
chooseSpan = filterArray.call(currentTable, item[rowIndex - 1])
}
if (chooseSpan) {
return {
rowspan: 0,
colspan: 0
}
} else {
return {
rowspan: item.filter(filterArray, currentTable).length,
colspan: 1
}
}
}
},
}
};
</script>
vue3 表格合并
vue3 hooks文件内容
// 定义通用类型(支持任意表格数据类型)
export interface TableSpanRule {
rule: Record<string, string[]>; // 列索引 → 合并字段列表
}
// 表格合并Hook
export function useTableSpan<T = Record<string, any>>(spanRule: TableSpanRule) {
const filterArray = (
currentTable: { rule: string[]; data: T },
item: T
): boolean => {
const valueArray = currentTable.rule.filter((prop) => {
return item[prop] === currentTable.data[prop];
});
return valueArray.length === currentTable.rule.length;
};
const objectSpanMethod = (
param: {
row: T;
column: T;
rowIndex: number;
columnIndex: number;
},
tableData: T[]
) => {
const { columnIndex, rowIndex } = param;
// 判断当前列是否在合并规则中
if (Object.keys(spanRule.rule).includes(columnIndex.toString())) {
const currentTable = {
rule: spanRule.rule[columnIndex],
data: tableData[rowIndex]
};
let chooseSpan = false;
// 非第一行时验证是否需要合并
if (rowIndex !== 0) {
chooseSpan = filterArray(currentTable, tableData[rowIndex - 1]);
}
// 需要合并则隐藏当前单元格,否则设置合并行数
if (chooseSpan) {
return {
rowspan: 0,
colspan: 0
};
} else {
return {
rowspan: tableData.filter((i) => filterArray(currentTable, i)).length,
colspan: 1
};
}
}
// 非合并列返回默认值
return {
rowspan: 1,
colspan: 1
};
};
return {
objectSpanMethod
};
}
vue3 表格合并
<el-table
:data="tableData"
:span-method="(param)=>objectSpanMethod(param,tableData)" //这里非常重要,tableData字段是表格的数据
border
style="width: 100%">
<el-table-column
prop="day"
label="day"
width="180">
</el-table-column>
<el-table-column
prop="domainName"
label="domainName">
</el-table-column>
<el-table-column
prop="allPurchaseCount"
sortable
label="allPurchaseCount">
</el-table-column>
<el-table-column
prop="allPurchaseValue"
sortable
label="allPurchaseValue">
</el-table-column>
<el-table-column
prop="gaAmountUsd"
sortable
label="交易额">
</el-table-column>
</el-table>
const tableCol = [ //表格列
{
label: t('localeAudience.datetime'),
prop: 'day',
width: 120,
sortable: "custom",
formatter: (row: any, column: any, text: any) => {
return text || "-";
},
},
{
label: t('localeAudience.domain'),
width: 120,
prop: 'domainName',
'show-overflow-tooltip': true,
},
{
label: t('localeAudience.allorders'),
sortable: "custom",
width: 120,
prop: 'allPurchaseCount',
},
{
label: t('localeAudience.allamount'),
sortable: "custom",
width: 140,
prop: 'allPurchaseValue',
},
{
label: '交易额',
sortable: "custom",
width: 180,
prop: 'gaAmountUsd',
},
];
const tableData = [ // 1.表格数据
{
day: '2023-08-01',
domainName: 'example.com',
allPurchaseCount: 10,
allPurchaseValue: 1000,
gaAmountUsd: 500,
},
{
day: '2023-08-01',
domainName: 'example.com',
allPurchaseCount: 5,
allPurchaseValue: 500,
gaAmountUsd: 250,
},
{
day: '2023-08-02',
domainName: 'example.com',
allPurchaseCount: 8,
allPurchaseValue: 800,
gaAmountUsd: 400,
},
];
// 2. 定义列合并规则
const spanRule = {
rule: {
0: ['day','domainName','allPurchaseCount','allPurchaseValue'], //表示第1列的合并规则
1: ['day','domainName','allPurchaseCount','allPurchaseValue'], //表示第2列的合并规则
2: ['day','domainName','allPurchaseCount','allPurchaseValue'], //表示第3列的合并规则
3: ['day','domainName','allPurchaseCount','allPurchaseValue'], //表示第4列的合并规则
}
};
// 3. 使用表格合并Hook
const { objectSpanMethod } = useTableSpan(spanRule);