害嗨海大家好,我又回来了。最近有小伙伴问了我这样一个问题,就是现在我调取接口,获取了一批表格数据,然后显示在页面上,但是要根据每行的id以及那一列的内容进行合并,然后还有添加子数据,编辑删除等操作(这里只说合并表格)
直接上图,直接渲染则是这个样子
需求:根据职业id合并行,第一列和最后一列都要合并,这要怎么做呢? 首先上template代码,这个没什么说,就是个el-table,操作那一列就是个作用域插槽
<template>
<div>
<el-table :data="tableData" :span-method="spanMethod">
<el-table-column prop="job" label="职业id">
</el-table-column>
<el-table-column prop="ename" label="名字"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
<el-table-column label="操作">
<template>
<el-button type="success" icon="el-icon-edit" size="mini"></el-button>
<el-button type="danger" icon="el-icon-delete" size="mini"></el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
其中,既然要合并单元格,我们当然要用到span-method了,翻译就是表格合并的方式。在html中,我们学习了rowspan和colspan,合并行和合并列。
下面就要写script的内容了,二话不说,直接上代码
<script>
export default {
data() {
return {
tableData: [
{
job: 1,
ename: "咕叽咕叽",
age: 21
},
{
job: 1,
ename: "哆啦哆啦",
age: 22
},
{
job: 2,
ename: "后端1",
age: 27
},
{
job: 2,
ename: "后端2",
age: 21
},
{
job: 2,
ename: "后端3",
age: 22
},
{
job: 3,
ename: "主管1",
age: 27
},
{
job: 3,
ename: "主管2",
age: 28
},
{
job: 4,
ename: "总监",
age: 28
},
]
}
},
methods: {
//合并的方法,里面row,colomn是这一行这一列的对象,rowIndex和colIndex就是行列的index 从0-n rowspan表示合并的行 大于1表示要往下合并了,然后下方被合并的rowspan就是0,0代表被合并了,1代表正常情况
spanMethod({ row, column, rowIndex, columnIndex }) {
//columnIndex代表哪几列需要合并,后面会用
let columnArr = [0, 3]
let jobArr = []; //所有职业id 从第一个数据到最后一个
for (let k in this.tableData) {
jobArr.push(this.tableData[k].job)
}
let obj = {}
for (let i = 0; i < jobArr.length; i++) {
if (obj[jobArr[i]] == undefined) {
obj[jobArr[i]] = 1
} else {
obj[jobArr[i]]++
}
}
console.log("obj", obj); //包含每个id以及其出现的次数,为后面合并做铺垫
let spanArr = []; //每一行就是一条数据,该数组每一个值就是当前行的rowspan数
let doneArr = [] //保存被合并了的id,如果再出现,表示被合并
for (let i = 0; i < jobArr.length; i++) {
//看看个数
if (doneArr.includes(jobArr[i])) {
//如果这个id被合并过了,说明刚刚上方有一样的id,这一项就是被合并的
spanArr.push(0)
} else {
//如果没合并,就往下合并,spanArr里推入这个id的个数,在obj中就有
spanArr.push(obj[jobArr[i]])
//别忘了合并完把id放进doneArr中
doneArr.push(jobArr[i])
}
}
//如果是第0列和第3列
if (columnArr.includes(columnIndex)) {
//遍历合并个数的数组
for (let i = 0; i < spanArr.length; i++) {
//如果是该行,行合并个数就是这一项的值,列不合并,所以是1
if (rowIndex == i) {
return {
rowspan: spanArr[i],
colspan: 1
}
}
}
}
}
},
}
</script>
rowspan表示合并的行,大于1表示要往下合并了,因此下方被合并的rowspan就是0,0代表被合并了,1代表正常情况(即不合并)
实际工作数据会更复杂,这个时候,需要合并的列/行就放在一个数组里,然后通过includes来判断这一列/行是否需要被合并。再算出spanArr(每一行需要合并的个数组成的数组),然后返回。
最后得出图如下
这就解决了问题,快去试一试吧!