有时我们在开发过程中会遇到表格里有合并单元格的需求。
今天以View UI (iview)组件库为例。
1. 打开iview官网-table会发现有合并单元格示例:
2. 但是在实际项目中,无法做到像上边代码那样通过 rowIndex
和 columnIndex
在前端将合并的单元格写死,而是需要根据后台返回给前端的数据进行逻辑判断,决定合并哪些单元格。
(1)比如现在有一个需求是表格的第一列“类别”中,如果有相同类别名字的进行单元格合并
<template>
<Table :columns="columns1" :data="data1" :span-method="handleSpan"></Table>
</template>
<script>
export default {
data () {
return {
columns1: [
{
title: '类别',
key: 'name'
},
{
title: '指标内容',
key: 'date'
}
],
data1: [
{
name: 'John Brown',
date: 18,
},{
name: 'John Brown',
date: 18,
},{
name: 'John Brown1',
date: 181,
},{
name: 'John Brown2',
date: 182,
},{
name: 'John Brown2',
date: 182,
},{
name: 'John Brown2',
date: 182,
},
]
}
},
methods: {
handleSpan ({
row, column, rowIndex, columnIndex }) {
}
}
}
</script>
页面如下:
(2)可知:第1、2行name值相同、第4、5、6行name值相同,下面研究如何合并第1行第1列、第2行第1列以及第4行第1列、第5行第1列、第6行第1列。
这里我们将data中的 data1改为 resData,而将 data1改为空数组,用 resData 模拟后台返回前端的数据.
注意:在合并行时,需要合并的数据必须相临,否则无法合并。这里我们直接将 resData 中需要合并的数据设为相临,即第1、2条以及第4、第5、第6条,在实际项目中这部分可以通过前端或者后端来操作这些数据,排序,使之相邻。
修改后的代码如下所示:
<template>
<Table :columns="columns1" :data="data1" :span-method="handleSpan"></Table>
</template>
<script>
export default {
data () {
return {
columns1: [
{
title: '类别',
key: 'name'
},
{
title: '指标内容',
key: 'date'
}
],
resData: [
{
name: 'John Brown',
date: 18,
},{
name: 'John Brown',
date: 18,
},{
name: 'John Brown1',
date: 181,
},{
name: 'John Brown2',
date: 182,
},{
name: 'John Brown2',
date: 182,
},{
name: 'John Brown2',
date: 182,
},
],
data1: []
}
},
methods: {
handleSpan ({
row, column, rowIndex, columnIndex }) {
}
}
}
</script>
(3)然后对 resData 中的数据进行处理,从而实现 name 值相同的行进行合并。
代码如下(具体说明已在代码块中添加注释):
<template>
<Table :columns="columns1" :data="data1" :span-method="handleSpan"></Table>
</template>
<script>
export default {
data () {
return {
columns1: [
{
title: '类别',
key: 'name'
},
{
title: '指标内容',
key: 'date'
}
],
resData: [
{
name: 'John Brown',
date: 18,
},{
name: 'John Brown',
date: 18,
},{
name: 'John Brown1',
date: 181,
},{
name: 'John Brown2',
date: 182,
},{
name: 'John Brown2',
date: 182,
},{
name: 'John Brown2',
date: 182,
},
],
data1: []
}
},
methods: {
handleSpan ({
row, column, rowIndex, columnIndex }) {
//合并第1列,这里columnIndex==0,根据需求的不同,需要前端写死
if(columnIndex == 0) {
//计算合并的行数列数
let x = row.mergeColumn == 0 ? 0:row.mergeColumn
let y = row.mergeColumn == 0 ? 0:1
return [x, y]
}
},
assembleData(data){
let names = []
//筛选出不重复的 name值,将其放到 names数组中
data.forEach(e => {
if(!names.includes(e.name)){
names.push(e.name)
}
})
let nameNums = []
//将names数组中的 name值设置默认合并0个单元格,放到 nameNums中
names.forEach(e => {
nameNums.push({
name:e,num:0})
})
//计算每种 name值所在行需要合并的单元格数
data.forEach(e => {
nameNums.forEach(n => {
if(e.name == n.name){
n.num++
}
})
})
//将计算后的合并单元格数整合到 data中
data.forEach(e => {
nameNums.forEach(n => {
if(e.name == n.name){
if(names.includes(e.name)){
e.mergeColumn = n.num
//删除已经设置过的值(防止被合并的单元格进到这个 if 语句中)
names.splice(names.indexOf(n.name),1)
} else {
//被合并的单元格设置为 0
e.mergeColumn = 0
}
}
})
})
//将整理后的数据交给表格渲染
this.data1 = data
}
},
mounted(){
//这里 this.resData即为后台返回的数据
this.assembleData(this.resData)
}
}
</script>
运行结果如下:
到这里,也就实现了我们想要的效果。
转载:https://blog.csdn.net/weixin_42881768/article/details/117117701
查看评论