<template>
<div class="table-merge-example">
<h2 class="title">Vue2 表格数据合并示例</h2>
<div class="table-container">
<h3>横向合并(列合并)</h3>
<table class="merge-table horizontal-merge">
<thead>
<tr>
<th>数值</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in processedHorizontalData" :key="index">
<td
:colspan="item.span"
:class="{ 'merged-cell': item.span > 1 }">
{{ item.value }}
</td>
</tr>
</tbody>
</table>
</div>
<div class="table-container">
<h3>纵向合并(行合并)</h3>
<table class="merge-table vertical-merge">
<thead>
<tr>
<th>序号</th>
<th>数值</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in originalData" :key="index">
<td>{{ index + 1 }}</td>
<td
:rowspan="verticalSpans[index]"
:class="{ 'merged-cell': verticalSpans[index] > 1 }"
v-if="verticalSpans[index] > 0">
{{ item }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
export default {
data() {
return {
originalData: [200, 300, 300, 300, 400, 400, 500],
processedHorizontalData: [],
verticalSpans: []
};
},
mounted() {
this.processHorizontalMerge();
this.processVerticalMerge();
},
methods: {
// 处理横向合并(列合并)
processHorizontalMerge() {
if (this.originalData.length === 0) {return;}
const result = [];
let currentValue = this.originalData[0];
let count = 1;
// 从第二个元素开始遍历
for (let i = 1; i < this.originalData.length; i++) {
if (this.originalData[i] === currentValue) {
count++;
} else {
// 保存当前组
result.push({ value: currentValue, span: count });
// 开始新的一组
currentValue = this.originalData[i];
count = 1;
}
}
// 添加最后一组
result.push({ value: currentValue, span: count });
this.processedHorizontalData = result;
},
// 处理纵向合并(行合并)
processVerticalMerge() {
if (this.originalData.length === 0) {return;}
const spans = new Array(this.originalData.length).fill(0);
let currentValue = this.originalData[0];
let count = 1;
spans[0] = 1;
// 从第二个元素开始遍历
for (let i = 1; i < this.originalData.length; i++) {
if (this.originalData[i] === currentValue) {
count++;
spans[i] = 0; // 被合并的单元格
} else {
// 设置上一组的合并数量
spans[i - count] = count;
// 开始新的一组
currentValue = this.originalData[i];
count = 1;
spans[i] = 1;
}
}
// 设置最后一组的合并数量
spans[this.originalData.length - count] = count;
this.verticalSpans = spans;
}
}
};
</script>
<style scoped>
.table-merge-example {
max-width: 800px;
margin: 20px auto;
padding: 20px;
font-family: Arial, sans-serif;
}
.title {
text-align: center;
color: #333;
margin-bottom: 30px;
}
.table-container {
margin-bottom: 40px;
border: 1px solid #e0e0e0;
border-radius: 6px;
padding: 15px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.table-container h3 {
color: #444;
margin-top: 0;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.merge-table {
width: 100%;
border-collapse: collapse;
text-align: center;
}
.merge-table th,
.merge-table td {
padding: 12px 15px;
border: 1px solid #ddd;
}
.merge-table th {
background-color: #f5f5f5;
font-weight: bold;
color: #555;
}
.merge-table tr:nth-child(even) {
background-color: #f9f9f9;
}
.merge-table tr:hover {
background-color: #f0f7ff;
}
.merged-cell {
background-color: #e6f7ff;
font-weight: bold;
color: #1890ff;
}
.horizontal-merge td {
border-right: 2px solid #fff;
}
.vertical-merge td {
border-bottom: 2px solid #fff;
}
</style>