官网解析
先看看官网示例
<template>
<Table
:columns="columns"
:data="data"
border
:span-method="handleSpan"
></Table>
</template>
<script>
export default {
data() {
return {
columns: [
{
title: "Date",
key: "date",
},
{
title: "Name",
key: "name",
},
{
title: "Age",
key: "age",
},
{
title: "Address",
key: "address",
},
],
data: [
{
name: "John Brown",
age: 18,
address: "New York No. 1 Lake Park",
date: "2016-10-03",
},
{
name: "Jim Green",
age: 24,
address: "London No. 1 Lake Park",
date: "2016-10-01",
},
{
name: "Joe Black",
age: 30,
address: "Sydney No. 1 Lake Park",
date: "2016-10-02",
},
{
name: "Jon Snow",
age: 26,
address: "Ottawa No. 2 Lake Park",
date: "2016-10-04",
},
],
};
},
methods: {
handleSpan({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0 && columnIndex === 0) {
return [1, 2];
} else if (rowIndex === 0 && columnIndex === 1) {
return [0, 0];
}
if (rowIndex === 2 && columnIndex === 0) {
return {
rowspan: 2,
colspan: 1,
};
} else if (rowIndex === 3 && columnIndex === 0) {
return {
rowspan: 0,
colspan: 0,
};
}
},
},
};
</script>

主要是设置 span-method
属性可以指定合并行或列的算法。
上面代码示例是根据行号和列号来进行合并判断的,现实情况我们很有可能需要动态判断合并的单元格。
注意:在合并行时,需要合并到数据必须相邻,数据在数组中的下标要紧挨这,否则无法合并。可以自己根据需要将数据排好序后再合并。
示例1:只根据某一列合并行
假设我们根据name
值相同的合并单元格
效果图:

代码实现:
<template>
<Table
:columns="columns"
:data="data"
border
:span-method="handleSpan"
></Table>
</template>
<script>
export default {
data() {
return {
columns: [
{
title: "Date",
key: "date",
},
{
title: "Name",
key: "name",
},
{
title: "Age",
key: "age",
},
{
title: "Address",
key: "address",
},
],
resData: [
{
id: "1",
name: "John Brown",
age: 18,
address: "New York No. 1 Lake Park",
date: "2016-10-03",
},
{
id: "3",
name: "John Brown",
age: 24,
address: "London No. 1 Lake Park",
date: "2016-10-01",
},
{
id: "2",
name: "Joe Black",
age: 30,
address: "Sydney No. 1 Lake Park",
date: "2016-10-02",
},
{
id: "4",
name: "Jon Snow",
age: 26,
address: "Ottawa No. 2 Lake Park",
date: "2016-10-04",
},
],
data: [],
};
},
methods: {
handleSpan({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 1) {
let x = row.mergeCol === 0 ? 0 : row.mergeCol;
let y = row.mergeCol === 0 ? 0 : 1;
return [x, y];
}
},
formatData(data) {
let names = [];
data.forEach((e) => {
if (!names.includes(e.name)) {
names.push(e.name);
}
});
let nameNums = [];
names.forEach((e) => {
nameNums.push({ name: e, num: 0 });
});
data.forEach((e) => {
nameNums.forEach((n) => {
if (e.name === n.name) {
n.num++;
}
});
});
data.forEach((e) => {
nameNums.forEach((n) => {
if (e.name === n.name) {
if (names.includes(e.name)) {
e.mergeCol = n.num;
names.splice(names.indexOf(n.name), 1);
} else {
e.mergeCol = 0;
}
}
});
});
return data;
},
},
mounted() {
this.data = this.formatData(this.resData);
},
};
</script>
示例2:先根据某一列合并行,再根据合并的行合并另一列中的行
什么意思,意思就是比如我先合并了name
列中相同的行,如果name
列已经合并的行中还有相同的age
列需要合并的话,应该怎么做?
数据预处理:先排序,把相同的name
值放到一起,然后再把相同的age
放到一起
效果图:

代码实现:
<template>
<Table
class="border-table"
:columns="columns"
:data="data"
border
:span-method="handleSpan"
></Table>
</template>
<script>
export default {
data() {
return {
columns: [
{
title: "Date",
key: "date",
},
{
title: "Name",
key: "name",
},
{
title: "Age",
key: "age",
},
{
title: "Address",
key: "address",
},
],
resData: [
{
id: "1",
name: "John Brown",
age: 18,
address: "New York No. 1 Lake Park",
date: "2016-10-03",
},
{
id: "3",
name: "John Brown",
age: 24,
address: "London No. 1 Lake Park",
date: "2016-10-01",
},
{
id: "5",
name: "John Brown",
age: 24,
address: "London No. 2 Lake Park",
date: "2016-10-03",
},
{
id: "2",
name: "Joe Black",
age: 30,
address: "Sydney No. 1 Lake Park",
date: "2016-10-02",
},
{
id: "4",
name: "Jon Snow",
age: 26,
address: "Ottawa No. 2 Lake Park",
date: "2016-10-04",
},
],
data: [],
};
},
methods: {
handleSpan({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 1) {
let x = row.mergeCol === 0 ? 0 : row.mergeCol;
let y = row.mergeCol === 0 ? 0 : 1;
return [x, y];
}
if (columnIndex === 2) {
let x = row.mergeColAge === 0 ? 0 : row.mergeColAge;
let y = row.mergeColAge === 0 ? 0 : 1;
return [x, y];
}
},
formatData(data) {
for (let i = 0; i < data.length - 1; i++) {
for (let n = i + 1; n < data.length; n++) {
if (data[i].age > data[n].age) {
[data[i], data[n]] = [data[n], data[i]];
}
}
}
let names = [];
data.forEach((e) => {
if (!names.includes(e.name)) {
names.push(e.name);
}
});
let nameNums = [];
names.forEach((e) => {
nameNums.push({ name: e, num: 0 });
});
data.forEach((e) => {
nameNums.forEach((n) => {
if (e.name === n.name) {
n.num++;
}
});
});
data.forEach((e) => {
nameNums.forEach((n) => {
if (e.name === n.name) {
if (names.includes(e.name)) {
e.mergeCol = n.num;
names.splice(names.indexOf(n.name), 1);
} else {
e.mergeCol = 0;
}
}
});
});
for (let j = 0; j < data.length; j++) {
if (data[j].mergeCol > 1) {
for (let k = 0; k < data[j].mergeCol; k++) {
if (data[j + k].ageAlready !== 1) {
if (k + 1 < data[j].mergeCol) {
data[j + k].mergeColAge = 1
for (let b = k + 1; b < data[j].mergeCol; b++) {
if (data[j + k].age === data[j + b].age) {
data[j + k].mergeColAge++;
data[j + b].mergeColAge = 0;
data[j + b].ageAlready = 1;
} else {
break;
}
}
}
}
}
}
}
return data;
},
},
mounted() {
this.data = this.formatData(this.resData);
},
};
</script>