不要把自己绕进去,这块儿很容易把自己想绕进去
主要就是因为我们平时都是在渲染数据所以下意识第一反应就是从行的角度去想然后再去从行的角度去包裹列就会发现 嗯?怎么没完没了了。
跳出行的思维去想列才是正确的,因为列才是页面上真正固定不变的内容。
这样想的话下面的代码就很好理解了。
下面的案例都是列内容一样时不同行合并
<vxe-table
border
resizable
:data="tableData"
:span-method="rowspanMethod"
>
<vxe-table-column type='seq' width="100"></vxe-table-column>
<vxe-table-column field="subjectCode" title="科目编码"></vxe-table-column>
<vxe-table-column field="subjectName" title="科目名称"></vxe-table-column>
<vxe-table-column field="money" title="金额"></vxe-table-column>
</vxe-table>
// 通用行合并函数(将相同多列数据合并为一行)||表格合并行
rowspanMethod({ row, $rowIndex, column, data }) {
const fields = ["subjectName", "subjectCode"];//存储你要合并的列的 field
const cellValue = this.$utils.get(row, column.property);//获取当前行当前列的内容
if (cellValue && fields.includes(column.property)) {//如果 当前行当前列的内容 不为空并且是需要合并的列
const prevRow = data[$rowIndex - 1];//获取前一行数据
let nextRow = data[$rowIndex + 1];//获取下一行数据
if (
prevRow &&
this.$utils.get(prevRow, column.property) === cellValue
) {//如果前一行数据不为空并且前一行当前列内容与本行本列内容一致 则合并
return { rowspan: 0, colspan: 0 };
} else {
//前一行内容为空或者前一行本列内容与本行本列内容不一致
let countRowspan = 1;
while (
nextRow &&
this.$utils.get(nextRow, column.property) === cellValue
) {
//当下一行内容不为空并且下一行当前列内容与本行本列内容一致时
nextRow = data[++countRowspan + $rowIndex];
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 };
}
}
}
},
this.$utils
是使用了XEUtils
事实上基本所有的表格插件的合并单元格都是一样的代码
比如element-ui
<el-table :data="tableData" :span-method="rowspanMethod">
<el-table-column field="subjectCode" title="科目编码"></el-table-column>
<el-table-column field="subjectName" title="科目名称"></el-table-column>
<el-table-column field="money" title="金额"></el-table-column>
</el-table>
rowspanMethod ({ row, column, rowIndex, columnIndex,data }){
const fields = ["subjectName", "subjectCode"]
const cellValue = row[column.property]
if (cellValue && fields.includes(column.property)) {
const prevRow = data[rowIndex - 1]
let nextRow = data[rowIndex + 1]
if (prevRow && prevRow[column.property] === cellValue) {
return { rowspan: 0, colspan: 0 }
} else {
let countRowspan = 1
while (nextRow && nextRow[column.property] === cellValue) {
nextRow = data[++countRowspan + rowIndex]
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 }
}
}
}
}
这里都是
vue2.0+
的写法
vue3.0
要用表格合并单元格的话也很简单
声明方法,箭头函数走一波
const data=reactive()
const rowspanMethod = ({ row, column, rowIndex, columnIndex })=>{
const fields = ["subjectName", "subjectCode"]
const cellValue = row[column.property]
if (cellValue && fields.includes(column.property)) {
const prevRow = data[rowIndex - 1]
let nextRow = data[rowIndex + 1]
if (prevRow && prevRow[column.property] === cellValue) {
return { rowspan: 0, colspan: 0 }
} else {
let countRowspan = 1
while (nextRow && nextRow[column.property] === cellValue) {
nextRow = data[++countRowspan + rowIndex]
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 }
}
}
}
}