Element 官网有合并单元格的例子
通过table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面是{row, column, rowIndex, columnIndex} 四个属性,该函数返回包含两个元素的数组,第一个代表rowspan,第二个代表colspan。也可以返回一个键名为rowspan 和 colspan的对象
<el-table
:data="tableData"
:span-method="arraySpanMethod"
border
style="width: 100%">
<el-table-column
prop="id"
label="ID"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名">
</el-table-column>
<el-table-column
prop="amount1"
sortable
label="数值 1">
</el-table-column>
<el-table-column
prop="amount2"
sortable
label="数值 2">
</el-table-column>
<el-table-column
prop="amount3"
sortable
label="数值 3">
</el-table-column>
</el-table>
<script>
export default {
data() {
return {
tableData: [{
id: '12987122',
name: '王小虎',
amount1: '234',
amount2: '3.2',
amount3: 10
}, {
id: '12987123',
name: '王小虎',
amount1: '165',
amount2: '4.43',
amount3: 12
}, {
id: '12987124',
name: '王小虎',
amount1: '324',
amount2: '1.9',
amount3: 9
}, {
id: '12987125',
name: '王小虎',
amount1: '621',
amount2: '2.2',
amount3: 17
}, {
id: '12987126',
name: '王小虎',
amount1: '539',
amount2: '4.1',
amount3: 15
}]
};
},
methods: {
arraySpanMethod({ row, column, rowIndex, columnIndex }) {
if (rowIndex % 2 === 0) {
if (columnIndex === 0) {
return [1, 2];
} else if (columnIndex === 1) {
return [0, 0];
}
}
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1
};
} else {
return {
rowspan: 0,
colspan: 0
};
}
}
}
}
};
</script>
注意:上面的数据格式和普通的表格数据格式没有区别,都是一条条的数据
往往后端传给前端的数据是下面的格式,含有嵌套的数组
tableData: [
{
id: 1,
name: "name-1",
data: [{ amount: 100 }, { amount: 200 }, { amount: 300 }]
},
{ id: 2, name: "name-2", data: [{ amount: 1002 }, { amount: 2002 }] },
{
id: 3,
name: "name-3",
data: [
{ amount: 1003 },
{ amount: 2003 },
{ amount: 3003 },
{ amount: 3004 }
]
}
]
这种格式的数据该怎么合并单元格呢?
1、首先进行数据格式转换,转换成符合官网的数据格式
2、生成合并信息的数组(那些列或者行要合并,哪些列或者行要隐藏)
3、使用span-method方法
效果图
完整代码
<template>
<div>
<el-table :data="tableData" :span-method="objectSpanMethod" border>
<el-table-column prop="id" label="ID" width="180"></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="amount" sortable label="数值"></el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
rowspan: "",
tableData: [
{
id: 1,
name: "name-1",
data: [{ amount: 100 }, { amount: 200 }, { amount: 300 }]
},
{ id: 2, name: "name-2", data: [{ amount: 1002 }, { amount: 2002 }] },
{
id: 3,
name: "name-3",
data: [
{ amount: 1003 },
{ amount: 2003 },
{ amount: 3003 },
{ amount: 3004 }
]
}
]
};
},
methods: {
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if ([0, 1].includes(columnIndex)) {
const _row = this.rowspan[rowIndex];
const _col = _row > 0 ? 1 : 0; // 如果这一行隐藏了,这列也隐藏
return {
rowspan: _row,
colspan: _col
};
}
},
convertTableData() {
let data = this.tableData;
let arr = [];
let rowspan = [];
data.forEach(item => {
//debugger
for (let i = 0; i < item.data.length; i++) {
let rdata = {
...item,
...item.data[i]
};
rdata.combineNum = item.data.length;
delete rdata.data;
// rdata={ id: 1,name: "name-1",amount: 1003}
arr.push(rdata);
// 生成合并信息的数组 [3, 0, 0, 2, 0, 4, 0, 0, 0] 其中的0代表隐藏
if (i == 0) {
rowspan.push(item.data.length);
} else {
rowspan.push(0);
}
}
});
//console.log(arr)
this.tableData = arr;
console.log(this.tableData);
console.log(rowspan);
this.rowspan = rowspan;
}
},
created() {
this.convertTableData();
}
};
</script>
上面的方法感觉还是比较麻烦的,有没有更简单的方法,方法是有的,其实我们只要按照数组正常循环就可以了,如果有嵌套数组就一个单元格中放几个div,底部加一条线,外观看起来跟合并单元格效果一样
需要解决的问题是一个单元格中有几条数据,怎么使DIV占满整个单元格,设置单元格的padding为0,
<el-table
:data="tableData"
style="width:100%;"
class="margin_b20 margin_t15"
:default-sort="{prop: 'addReducePercent', order: 'descending'}"
:cell-style="cellStylePadding0"
id="bigTable"
>
<el-table-column label="客户名称" prop="customeName" min-width="150px"></el-table-column>
<el-table-column label="客户地址" prop="customAddress" min-width="200px;"></el-table-column>
<el-table-column
prop="addReduceQty"
min-width="110"
label="增减量"
header-align="center"
align="right"
>
<template slot-scope="scope">
<div v-if="scope.row.addReduceQty>200" style="color:green">{{scope.row.addReduceQty}}</div>
<div v-else style="color:red">{{scope.row.addReduceQty}}</div>
</template>
</el-table-column>
<el-table-column
prop="addReducePercent"
min-width="130"
label="增减百分比"
header-align="center"
align="right"
sortable
:sort-method="handleSort"
></el-table-column>
</el-table-column>
<el-table-column label="分路计量" header-align="center">
<el-table-column label="名称" prop="branchName">
<template slot-scope="scope">
<div class="branchWrap">
<div
v-for="(item,index) in scope.row.branchInfo"
:key="index"
class="lineHeight28"
>{{item.name}}</div>
</div>
</template>
</el-table-column>
<el-table-column
:label="lastTime"
header-align="center"
align="right"
min-width="120px"
prop="branchLastTime"
>
<template slot-scope="scope">
<div class="branchWrap">
<div
v-for="(item,index) in scope.row.branchInfo"
:key="index"
class="lineHeight28"
>{{item.lastTimeQty}}</div>
</div>
</template>
</el-table-column>
<el-table-column
:label="thisTime"
header-align="center"
align="right"
min-width="120px"
prop="branchThisTime"
>
<template slot-scope="scope">
<div class="branchWrap">
<div
v-for="(item,index) in scope.row.branchInfo"
:key="index"
class="lineHeight28"
>{{item.thisTimeQty}}</div>
</div>
</template>
</el-table-column>
<el-table-column label="增减量" header-align="center" align="right" prop="branchAddReduceQty">
<template slot-scope="scope">
<div class="branchWrap">
<div
v-for="(item,index) in scope.row.branchInfo"
:key="index"
class="lineHeight28"
><span style="color:green;" v-if="item.addReduceQty>100">{{item.addReduceQty}}</span>
<span style="color:red;" v-else>{{item.addReduceQty}}</span>
</div>
</div>
</template>
</el-table-column>
</el-table-column>
</el-table>
设置padding为0 的方法
cellStylePadding0({ row, column, ronIndex, columnIndex }) {
if (
column.property == "branchName" ||
column.property == "branchLastTime" ||
column.property == "branchThisTime" ||
column.property == "branchAddReduceQty" ||
column.property == "branchAddReducePercent"
) {
return "padding:0";
} else {
return "";
}
//console.log(column.property)
},
上面的例子出现百分比的比较
handleSort(obja, objb) {
let a = this.toPoint(obja.addReducePercent);
let b = this.toPoint(objb.addReducePercent);
console.log(a, b);
if (a > b) {
return 1;
} else {
return -1;
}
},
/*百分数转小数*/
toPoint(percent) {
var str = percent.replace("%", "");
str = str / 100;
return str;
},
样式
<style scoped>
.textRadio >>> .el-radio__label {
display: none;
}
.branchWrap {
margin: 0 -10px;
}
.branchWrap div {
padding: 0 10px;
border-bottom: 1px solid #dfe6ec;
}
.branchWrap div:last-child {
border: none;
}
.lineHeight28 {
line-height: 28px;
}
</style>