基础知识
我们先来分析一波 iview 官网中的合并单元格(iview和elementui合并单元格代码差不多):
handleSpan ({ row, column, rowIndex, columnIndex }) {
// 设置要合并的行和要合并的列
if (rowIndex === 0 && columnIndex === 0) {
// 分别代表合并的行数和列数
return [1, 2];
} else if (rowIndex === 0 && columnIndex === 1) {
// 分别代表合并的行数和列数,设为0则直接不显示
return [0, 0];
}
if (rowIndex === 2 && columnIndex === 0) {
return {
rowspan: 2,
colspan: 1
};
} else if (rowIndex === 3 && columnIndex === 0) {
return {
rowspan: 0,
colspan: 0
};
}
}
效果:
但是这种行和列直接写死了,而我们一般 table 的数据都是动态渲染的,所以我们需要改造一下。
改造
具体解释在代码中:
<template>
<div class="hello">
<template>
<Table :columns="columns14"
:data="data5"
border
:span-method="handleSpan"></Table>
</template>
</div>
</template>
<script>
export default {
data () {
return {
columns14: [
{
title: 'Date',
key: 'date'
},
{
title: 'Name',
key: 'name'
},
{
title: 'Age',
key: 'age'
},
{
title: 'Address',
key: 'address'
}
],
data5: [
{
name: 'Jim Green',
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'
}
],
spanArr: [],
pos: NaN
}
},
mounted () {
// 页面初始化的时候先对this.data5做一下分析,得到新数组spanArr
this.getSpanArr(this.data5)
console.log(this.spanArr)
},
methods: {
handleSpan ({ row, column, rowIndex, columnIndex }) {
// 我们需要只需要合并第二列(columnIndex === 1)name字段如果有相同的合并,其他字段我们不管
if (columnIndex === 1) {
// 第一个参数,合并几行,例子中我们合并2行,也就是新数组中的2
const _row = this.spanArr[rowIndex]
// 第二个参数,合并几列,我们只需要合并一列(name字段的那一列,如果为2,则还要合并age那一列,不符合我们需求)
// 所以只要是数组中的数字大于0,我们第二个参数就为1,否则为0
const _col = _row > 0 ? 1 : 0
// 这里的{ row, column, rowIndex, columnIndex }几个参数其实相当于遍历,每次渲染都会触发,所以会把每一行都正确渲染
return {
rowspan: _row,
colspan: _col
}
}
},
// 得到一个新数组spanArr=[2,0,1],代表前两个要合并,做成这种主要是为了迎合iview中的格式
getSpanArr (data) {
for (var i = 0; i < data.length; i++) {
// 第一轮,此时新数组spanArr=[1]
if (i === 0) {
this.spanArr.push(1)
this.pos = 0
continue
}
// 判断当前元素与上一个元素的name是否相同
if (data[i].name === data[i - 1].name) {
this.spanArr[this.pos] += 1
this.spanArr.push(0)
// 第二轮,假设走这里,则此时为新数组为[2,0]
} else {
this.spanArr.push(1)
this.pos = i
// 第三轮,假设走这里,则此时为新数组为[2,0,1]
}
}
}
}
}
</script>
效果:
优化
可以将某些变量提取出来,使用的时候只需要传参就好了,有空了再更新~