整体实现效果图是这样
只写了合并部分列的代码
// columns 是a-table列表的表头及参数
columns: [
{
title: "资源等级",
dataIndex: "sourceLevel",
width: 160,
key: "sourceLevel",
align: "center",
scopedSlots: {
customRender: 'sourceLevel' // 写了sourceLevel这个我们仍可以在html上面写插槽来写入选择框
},
customCell: (record, rowIndex) => {
return this.mergeCellsSlot(record, rowIndex); // this.mergeCellsSlot 下面有合并行的具体代码
},
},
{
title: "系数",
dataIndex: "coefficient",
width: 70,
key: "coefficient",
align: "center",
customRender(_, row) {
return {
children: row.coefficient,
attrs: {
rowSpan: row.coefficientRowSpan
}
};
}
}
]
2.上面插槽的写法
<template
v-for="col in ['workingHours', 'sourceLevel']"
:slot="col"
slot-scope="text, record"
>
<div :key="col">
<a-select
v-model="record.Resource"
placeholder="请选择"
:showArrow="true"
style="display: block;"
v-if="col == 'workingHours'"
@change="workingHoursOnChangeSelect($event, record.key, col, 'dailyPrice')">
<a-select-option v-for="(item,index) in workingOptions" :key="index" :value="item.typeCode">{{ item.typeName }}</a-select-option>
</a-select>
<a-select
v-model="record.sourceLevel"
placeholder="请选择"
:showArrow="true"
style="display: block;"
v-if="col == 'sourceLevel'"
@change="workingHoursOnChangeSelect($event, record.key, col, 'coefficient')">
<a-select-option v-for="(item,index) in sourceLevelOptions" :key="index" :value="item.typeCode">{{ item.typeName }}</a-select-option>
</a-select>
</div>
</template>
下拉框change事件
// select 框 change
workingHoursOnChangeSelect($event, rowKey, colName, val) {
const newData = [...this.tabularData];
const target = newData.filter(item => rowKey === item.key)[0];
if (target) {
target[val] = $event;
this.tabularData = newData;
}
},
这两个合并的方法都可以写上
_this.rowSpan("age");
_this.rowSpan("Resource");
_this.rowSpan("dailyPrice");
_this.rowSpan("sourceLevel");
_this.rowSpan("coefficient");
// 合并
rowSpan(key) {
const arr = this.tabularData
.reduce((result, item) => {
if (result.indexOf(item[key]) < 0) {
result.push(item[key]);
}
return result;
}, [])
.reduce((result, keys) => {
const children = this.tabularData.filter(item => item[key] === keys);
result = result.concat(children.map((item, index) => ({...item, [`${key}RowSpan`]: index === 0 ? children.length : 0})));
return result;
}, []);
this.tabularData = arr;
},
这个是合并单元格的具体代码
// 合并单元格
mergeCellsSlot(record, rowIndex) {
// 开始下标
const index = this.tabularData.findIndex((item) => item.id === record.id);
// 需要合并的单元格数
let rowSpanNum = 0;
this.tabularData.forEach((item) => {
if (item.id === record.id) {
rowSpanNum++;
}
});
// 结束下标
const indexIdLength = index + rowSpanNum;
return {
style: { display: index < rowIndex && rowIndex < indexIdLength ? "none" : undefined },
attrs: { rowSpan: rowIndex === index ? rowSpanNum : 1 }
};
}
1.具体实现逻辑就是在设置table表头加上内容的插槽和合并单元格的函数,
2.在上面插槽下拉框要绑定table循环的值,不然会选不中内容
3.给合并的单元格赋值可以通过table数组[下标]来赋值