vue 可合并表格组件_Element-UI el-table 表格动态合并行和列
前言
示例版本为 Element-UI 2.13.2 + Vue 2.6.11
基于项目业务需求,最近开发了一个支持自动合并行列的表格组件,并具备行列智能合并功能;该组件对于数据格式有特定的要求。
Element-UI 该组件提供了将表单元格合并的操作范例;然而对于较为复杂的功能模块而言,在编写组件之前查阅了相关参考资料,并未找到匹配的相关案例;因此决定将这一发现与大家分享。
预设数据
组件在定义之前需要提前预设几个属性:
tableData:表格中的数据
colConfigs:表格列的内容信息
mergeColumns:要合并的列信息
tableData
示例中的数据格式:
[
{ time: '2020-08-10', grade: '三年二班', name: '小明', subjects: '语文' },
{ time: '2020-08-10', grade: '三年二班', name: '小明', subjects: '数学' },
{ time: '2020-08-10', grade: '总成绩', name: '总成绩', subjects: '总成绩' },
{ time: '2020-08-10', grade: '三年一班', name: '小雷', subjects: '语文' },
{ time: '2020-08-10', grade: '三年一班', name: '小雷', subjects: '数学' },
{ time: '2020-08-10', grade: '总成绩', name: '总成绩', subjects: '总成绩' },
{ time: '2020-08-11', grade: '三年三班', name: '小花', subjects: '语文' },
{ time: '2020-08-11', grade: '三年三班', name: '小花', subjects: '数学' },
{ time: '2020-08-11', grade: '总成绩', name: '总成绩', subjects: '总成绩' }
]
复制代码
colConfigs
表格列的内容信息:
[
{
label: '考试信息',
align: 'center',
type: 'label',
children: [
{ prop: 'time', label: '考试时间', align: 'center' },
{ prop: 'grade', label: '所在班级', align: 'center' },
{ prop: 'name', label: '考生姓名', align: 'center' },
{ prop: 'subjects', label: '考试科目', align: 'center' }
]
},
{ prop: 'results', label: '考试成绩', align: 'center', type: 'input' },
{ prop: 'remark', label: '备注', align: 'center', type: 'input' }
]
复制代码
参数说明label显示的标题(element-ui原始属性)
align对齐方式(element-ui原始属性)
width对应列的宽度(element-ui原始属性)
prop对应列内容的字段名(element-ui原始属性)
formatter用来格式化内容(element-ui原始属性)
指定自定义属性时,默认将其划分为'label'类别和其他属性。其中'label'列为固定不变的列名字段,其他字段则可通过相应配置实现个性化设置
children自定义属性,存在合并列的情况
mergeColumns
要合并的列信息数据格式:
[
{ index: 2, name: 'time' },
{ index: 3, name: 'grade' },
{ index: 4, name: 'name' },
{ index: 5, name: 'subjects' }
]
复制代码
参数说明index所在表格中的列下标
name要合并的字段名称
定义组件
将预设的数据通过 props 参数传递给定义好的组件。当 el-table 组件的内容未进行合并时,其默认坐标信息为 [1,1]。若出现 0 坐标(如 [0,1]),则会隐藏对应的单元格。反之若坐标为 [1,2] 则会将相邻的单元格进行合并。表格的合并逻辑如下:在组件加载过程中,根据 tableData 和 mergeColumns 生成新的坐标信息,并利用 Element 提供的 span 方法实现单元格的合并。
生成坐标数组信息
// 遍历表格中需要合并的所有单元格
for (let i = 0; i < this.tableData.length; i++) {
for (let j = 0; j < this.mergeColumns.length; j++) {
// 初始化行、列坐标信息
let rowIndex = 1
let columnIndex = 1
// 比较横坐标左方的第一个元素
当j大于零时,在合并后的列中比较当前单元格的值是否等于前一列的值。
columnIndex = 0
}
// 比较纵坐标上方的第一个元素
当i大于0时, this.tableData[i][this.mergeColumns[j]['name']]等于$this.tableData[i-1][this.mergeColumns[j]['name']]吗?
rowIndex = 0
}
// 比较横坐标右方元素
if (columnIndex > 0) {
该列索引将被赋值为当前实例中获取该列索引的方法计算得到的结果。
}
// 比较纵坐标下方元素
if (rowIndex > 0) {
currentRowIndex is assigned by the method calculateRowIndex within the context of table data and merge columns.
}
const key = this.mergeColumns[j]['index'] + '_' + i
this.tableMergeData[key] = [rowIndex, columnIndex]
}
}
复制代码
对每个需要合并的数据单元格进行遍历,并将每个单元格与其相邻的单元格进行内容对比。随后,将新坐标存入当前坐标的记录中,并通过Element对象调用span方法来获取合并后的数据结果。
mergeCols({ rowIndex, columnIndex }) {
const key = columnIndex + '_' + rowIndex
if (this.tableMergeData[key]) {
return this.tableMergeData[key]
}
}
复制代码
结尾
完整源码放在 GitHub 上了,希望可以帮助到你。
