Vue之vxe-table表格合并行应用指南
作者:风轻轻~
想要表格相同列数据智能合并?vxe-table合并单元格教程来啦!本指南教你使用span-method灵活合并行,并深入讲解如何根据字段进行拓展合并与排序,点击即可掌握让表格显示更清晰的核心技巧
vxe-table 地址:https://vxetable.cn/v2/#/table/start/install
一. 将相同的列数据合并为一行
实现效果

实现方法
使用 API 中的 span-method 方法:

span-method 使用方法
<vxe-grid border resizable align="center" :columns="tableColumn" :data="tableData" :span-method="rowspanMethod" > </vxe-grid>
// 将相同的列数据合并为一行
rowspanMethod({ row, _rowIndex, column, visibleData }) {
// 需要合并的列字段
let fields = [];
const cellValue = row[column.property];
if (cellValue && fields.includes(column.property)) {
const prevRow = visibleData[_rowIndex - 1];
let nextRow = visibleData[_rowIndex + 1];
if (prevRow && prevRow[column.property] === cellValue) {
return { rowspan: 0, colspan: 0 };
} else {
let countRowspan = 1;
while (nextRow && nextRow[column.property] === cellValue) {
nextRow = visibleData[++countRowspan + _rowIndex];
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 };
}
}
}
}
完整代码
<template>
<div class="page">
<vxe-grid
border
resizable
align="center"
:columns="tableColumn"
:data="tableData"
:span-method="rowspanMethod"
>
</vxe-grid>
</div>
</template>
<script>
export default {
data() {
return {
tableColumn: [
{ type: "seq", field: "seq", width: 50 },
{ field: "bus", title: "公交班次" },
{ field: "upDown", title: "上下行" },
{ field: "strStation", title: "进站" },
{ field: "endStation", title: "出站" },
{ field: "guestNum", title: "上下行总客数" }
],
tableData: [
{
bus: "1路",
upDown: "上行",
strStation: "B站",
endStation: "A站",
guestNum: 98
},
{
bus: "1路",
upDown: "下行",
strStation: "A站",
endStation: "B站",
guestNum: 98
},
{
bus: "2路",
upDown: "下行",
strStation: "C站",
endStation: "B站",
guestNum: 95
},
{
bus: "2路",
upDown: "上行",
strStation: "B站",
endStation: "C站",
guestNum: 95
},
{
bus: "3路",
upDown: "上行",
strStation: "B站",
endStation: "D站",
guestNum: 95
},
{
bus: "3路",
upDown: "下行",
strStation: "D站",
endStation: "B站",
guestNum: 95
},
{
bus: "4路",
upDown: "下行",
strStation: "D站",
endStation: "C站",
guestNum: 102
},
{
bus: "4路",
upDown: "上行",
strStation: "C站",
endStation: "D站",
guestNum: 102
}
]
};
},
methods: {
// 将相同的列数据合并为一行
rowspanMethod({ row, _rowIndex, column, visibleData }) {
// 需要合并的列字段
let fields = ["bus", "upDown", "strStation", "endStation", "guestNum"];
const cellValue = row[column.property];
if (cellValue && fields.includes(column.property)) {
const prevRow = visibleData[_rowIndex - 1];
let nextRow = visibleData[_rowIndex + 1];
if (prevRow && prevRow[column.property] === cellValue) {
return { rowspan: 0, colspan: 0 };
} else {
let countRowspan = 1;
while (nextRow && nextRow[column.property] === cellValue) {
nextRow = visibleData[++countRowspan + _rowIndex];
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 };
}
}
}
}
}
};
</script>
<style scoped>
.page {
width: 100%;
height: 100%;
padding: 20px;
box-sizing: border-box;
}
</style>
二. 拓展合并:根据某个字段合并后的数据 进行合并其他字段列
需求: 排序字段 根据 公交班次 合并后的数据进行排序,上下行总客数 根据 公交班次 合并后的数据
实现效果

实现方法
使用 API 中的 span-method、seq-config 方法:


span-method、seq-config 使用方法
<vxe-grid
border
resizable
align="center"
:columns="tableColumn"
:data="tableData"
:span-method="rowspanMethod"
:seq-config="{ seqMethod }"
>
</vxe-grid>columns 列配置 中的排序项 需要添加field: "seq"
tableColumn: [
{ type: "seq", field: "seq", width: 50 },
{ field: "bus", title: "公交班次" },
{ field: "upDown", title: "上下行" },
{ field: "strStation", title: "进站" },
{ field: "endStation", title: "出站" },
{ field: "guestNum", title: "上下行总客数" }
],
/**
*自定义合并:根据某个字段合并后的数据 进行合并其他字段列
*/
rowspanMethod({
row,
items,
seq,
rowIndex,
$rowIndex,
_rowIndex,
column,
visibleData,
data
}) {
/**
* 相同的列数据 自定义合并
* 此处自定义合并的字段:seq、guestNum
* 此处的合并参考字段:bus
*/
if (column.property === "seq") {
// 合并参考字段,根据此字段进行合并行
const referenceField = "bus";
if (rowIndex > 0) {
if (row[referenceField] === items[rowIndex - 1][referenceField]) {
row.seq = items[rowIndex - 1].seq;
} else {
row.seq = items[rowIndex - 1].seq + 1;
}
} else if (rowIndex === 0) {
row.seq = seq;
}
let prevRow = data[$rowIndex - 1];
let nextRow = data[$rowIndex + 1];
if (prevRow && prevRow[referenceField] === row[referenceField]) {
return { rowspan: 0, colspan: 0 };
} else {
let countRowspan = 1;
while (nextRow && nextRow[referenceField] === row[referenceField]) {
nextRow = data[++countRowspan + $rowIndex];
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 };
}
}
} else {
/**
* 相同的列数据 默认合并
* 此处合并的列字段:["bus"]
*/
// 需要合并的列字段
let fields = ["bus"];
const cellValue = row[column.property];
if (cellValue && fields.includes(column.property)) {
const prevRow = visibleData[_rowIndex - 1];
let nextRow = visibleData[_rowIndex + 1];
if (prevRow && prevRow[column.property] === cellValue) {
return { rowspan: 0, colspan: 0 };
} else {
let countRowspan = 1;
while (nextRow && nextRow[column.property] === cellValue) {
nextRow = visibleData[++countRowspan + _rowIndex];
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 };
}
}
}
}
},
/**
* 自定义排序
* 此处的合并参考字段:bus
*/
seqMethod(obj) {
// 合并参考字段
const referenceField = "bus";
obj.row.seq = obj.seq;
if (obj.rowIndex > 0) {
if (obj.seq - obj.items[obj.rowIndex - 1].seq > 1) {
if (
obj.row[referenceField] ===
obj.items[obj.rowIndex - 1][referenceField]
) {
obj.row.seq = obj.items[obj.rowIndex - 1].seq;
return obj.items[obj.rowIndex - 1].seq;
} else {
obj.row.seq = obj.items[obj.rowIndex - 1].seq + 1;
return obj.items[obj.rowIndex - 1].seq + 1;
}
} else {
obj.row.seq = obj.items[obj.rowIndex - 1].seq + 1;
return obj.items[obj.rowIndex - 1].seq + 1;
}
} else {
return obj.seq;
}
}
完整代码
<template>
<div class="page">
<vxe-grid
border
resizable
align="center"
:columns="tableColumn"
:data="tableData"
:span-method="rowspanMethod"
:seq-config="{ seqMethod }"
>
</vxe-grid>
</div>
</template>
<script>
export default {
data() {
return {
tableColumn: [
{ type: "seq", field: "seq", width: 50 },
{ field: "bus", title: "公交班次" },
{ field: "upDown", title: "上下行" },
{ field: "strStation", title: "进站" },
{ field: "endStation", title: "出站" },
{ field: "guestNum", title: "上下行总客数" }
],
tableData: [
{
bus: "1路",
upDown: "上行",
strStation: "B站",
endStation: "A站",
guestNum: 98
},
{
bus: "1路",
upDown: "下行",
strStation: "A站",
endStation: "B站",
guestNum: 98
},
{
bus: "2路",
upDown: "下行",
strStation: "C站",
endStation: "B站",
guestNum: 95
},
{
bus: "2路",
upDown: "上行",
strStation: "B站",
endStation: "C站",
guestNum: 95
},
{
bus: "3路",
upDown: "上行",
strStation: "B站",
endStation: "D站",
guestNum: 95
},
{
bus: "3路",
upDown: "下行",
strStation: "D站",
endStation: "B站",
guestNum: 95
},
{
bus: "4路",
upDown: "下行",
strStation: "D站",
endStation: "C站",
guestNum: 102
},
{
bus: "4路",
upDown: "上行",
strStation: "C站",
endStation: "D站",
guestNum: 102
}
]
};
},
methods: {
/**
*自定义合并:根据某个字段合并后的数据 进行合并其他字段列
*/
rowspanMethod({
row,
items,
seq,
rowIndex,
$rowIndex,
_rowIndex,
column,
visibleData,
data
}) {
/**
* 相同的列数据 自定义合并
* 自定义合并的字段:seq、guestNum
* 此处的合并参考字段:bus
*/
if (column.property === "seq" || column.property === "guestNum") {
// 合并参考字段,根据此字段进行合并行
const referenceField = "bus";
if (rowIndex > 0) {
if (row[referenceField] === items[rowIndex - 1][referenceField]) {
row.seq = items[rowIndex - 1].seq;
} else {
row.seq = items[rowIndex - 1].seq + 1;
}
} else if (rowIndex === 0) {
row.seq = seq;
}
let prevRow = data[$rowIndex - 1];
let nextRow = data[$rowIndex + 1];
if (prevRow && prevRow[referenceField] === row[referenceField]) {
return { rowspan: 0, colspan: 0 };
} else {
let countRowspan = 1;
while (nextRow && nextRow[referenceField] === row[referenceField]) {
nextRow = data[++countRowspan + $rowIndex];
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 };
}
}
} else {
/**
* 相同的列数据 默认合并
* 此处合并的列字段:["bus"]
*/
// 需要合并的列字段
let fields = ["bus"];
const cellValue = row[column.property];
if (cellValue && fields.includes(column.property)) {
const prevRow = visibleData[_rowIndex - 1];
let nextRow = visibleData[_rowIndex + 1];
if (prevRow && prevRow[column.property] === cellValue) {
return { rowspan: 0, colspan: 0 };
} else {
let countRowspan = 1;
while (nextRow && nextRow[column.property] === cellValue) {
nextRow = visibleData[++countRowspan + _rowIndex];
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 };
}
}
}
}
},
/**
* 自定义排序
* 此处的合并参考字段:bus
*/
seqMethod(obj) {
// 合并参考字段
const referenceField = "bus";
obj.row.seq = obj.seq;
if (obj.rowIndex > 0) {
if (obj.seq - obj.items[obj.rowIndex - 1].seq > 1) {
if (
obj.row[referenceField] ===
obj.items[obj.rowIndex - 1][referenceField]
) {
obj.row.seq = obj.items[obj.rowIndex - 1].seq;
return obj.items[obj.rowIndex - 1].seq;
} else {
obj.row.seq = obj.items[obj.rowIndex - 1].seq + 1;
return obj.items[obj.rowIndex - 1].seq + 1;
}
} else {
obj.row.seq = obj.items[obj.rowIndex - 1].seq + 1;
return obj.items[obj.rowIndex - 1].seq + 1;
}
} else {
return obj.seq;
}
}
}
};
</script>
<style scoped>
.page {
width: 100%;
height: 100%;
padding: 20px;
box-sizing: border-box;
}
</style>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
