Web前端之Vue+Element实现表格动态不同列合并多行、localeCompare、forEach、table、push、sort、Map
MENU
- 效果图
- 公共数据
- 数据未排序时(需要合并的行数据未处于相邻位置)
- 固定合并行(写死)
- 动态合并行
- 方法(函数)执行
效果图
公共数据
Html
<el-table :data="tableData" :span-method="changeSpanMethod" borderstyle="width: 100%; margin-top: 20px"><el-table-column prop="department" label="科室" width="168px"></el-table-column><el-table-column prop="name" label="姓名"></el-table-column><el-table-column prop="amount1" label="特色套餐"></el-table-column><el-table-column prop="amount2" label="价格"></el-table-column><el-table-column prop="amount3" label="菜肴名称"></el-table-column><el-table-column prop="amount4" label="制作物料"></el-table-column>
</el-table>
JavaScript
// 数据
tableData: [{department: '急诊大厅',name: '张三',amount1: '桂林米粉套餐',amount2: '5.50',amount3: '米饭',amount4: '水70g'},{department: '急诊大厅',name: '张三',amount1: '桂林米粉套餐',amount2: '5.50',amount3: '油豆腐炒肉',amount4: '猪里脊20g'},{department: '急诊大厅',name: '张三',amount1: '桂林米粉套餐',amount2: '5.50',amount3: '油豆腐炒肉',amount4: '油果50g'},{department: '急诊大厅',name: '张三',amount1: '桂林米粉套餐',amount2: '5.50',amount3: '米饭',amount4: '香米50g'},{department: '急诊大厅',name: '张三',amount1: '桂林米粉套餐',amount2: '5.50',amount3: '油豆腐炒肉',amount4: '葱花2g'},{department: '急诊大厅',name: '王五',amount1: '包子铺',amount2: '1.50',amount3: '水晶包',amount4: '肥肉10g'},{department: '急诊大厅',name: '张三',amount1: '桂林米粉套餐',amount2: '5.50',amount3: '油豆腐炒肉',amount4: '蒜米5g'},{department: '急诊大厅',name: '张三',amount1: '桂林米粉套餐',amount2: '5.50',amount3: '油豆腐炒肉',amount4: '豆油2g'}, {department: '急诊大厅',name: '王五',amount1: '包子铺',amount2: '1.50',amount3: '水晶包',amount4: '糖10g'},{department: '急诊大厅',name: '张三',amount1: '桂林米粉套餐',amount2: '5.50',amount3: '油豆腐炒肉',amount4: '盐2g'},{department: '急诊大厅',name: '张三',amount1: '桂林米粉套餐',amount2: '5.50',amount3: '油豆腐炒肉',amount4: '酱油3g'},{department: '急诊大厅',name: '李四',amount1: '早餐1',amount2: '6.00',amount3: '小米粥',amount4: '香米20g'},{department: '急诊大厅',name: '李四',amount1: '早餐1',amount2: '6.00',amount3: '煎蛋',amount4: '鸡蛋50g'},{department: '急诊大厅',name: '王五',amount1: '包子铺',amount2: '1.50',amount3: '水晶包',amount4: '面粉50g'},{department: '急诊大厅',name: '李四',amount1: '早餐1',amount2: '6.00',amount3: '小米粥',amount4: '水70g'},{department: '急诊大厅',name: '李四',amount1: '早餐1',amount2: '6.00',amount3: '煎蛋',amount4: '油20g'},{department: '急诊大厅',name: '李四',amount1: '早餐1',amount2: '6.00',amount3: '榨菜',amount4: '榨菜20g'}
],
spanConfig: ['department', 'name', 'amount1', 'amount2', 'amount3'],
spanMap: new Map()
数据未排序时(需要合并的行数据未处于相邻位置)
// 排序方法
groupByKeys(keyLis) {let list = this.tableData;let res = list.sort((a, b) => {// localeCompare汉字排序const sor1 = b[keyLis[0]].localeCompare(a[keyLis[0]], 'zh');if (sor1 !== 0) return sor1;return a[keyLis[1]].localeCompare(b[keyLis[1]], 'zh');});this.tableData = res;
}
固定合并行(写死)
changeSpanMethod({row,column,rowIndex,columnIndex
}) {if (columnIndex === 0) {if (rowIndex === 0) {return {rowspan: 11,colspan: 1};} else {return {rowspan: 0,colspan: 0};}}if (columnIndex === 1) {if (rowIndex === 0) {return {rowspan: 8,colspan: 1};} else if (rowIndex === 8) {return {rowspan: 3,colspan: 1};} else {return {rowspan: 0,colspan: 0};}}if (columnIndex === 2) {if (rowIndex === 0) {return {rowspan: 8,colspan: 1};} else if (rowIndex === 8) {return {rowspan: 3,colspan: 1};} else {return {rowspan: 0,colspan: 0};}}if (columnIndex === 3) {if (rowIndex === 0) {return {rowspan: 8,colspan: 1};} else if (rowIndex === 8) {return {rowspan: 3,colspan: 1};} else {return {rowspan: 0,colspan: 0};}}if (columnIndex === 4) {if (rowIndex === 0) {return {rowspan: 1,colspan: 1};} else if (rowIndex === 1) {return {rowspan: 7,colspan: 1};} else if (rowIndex >= 2 && rowIndex <= 7) {return {rowspan: 0,colspan: 0};} else {return {rowspan: 1,colspan: 1};}}
}
动态合并行
// 合并行数计算
calculateSpans() {const spanConfig = this.spanConfig;const tempMap = new Map();spanConfig.forEach(prop => {const spans = [];let position = 0;this.tableData.forEach((item, index) => {if (index === 0) {spans.push(1);position = 0;} else {// 当前行内容与上一行相同if (this.tableData[index][prop] === this.tableData[index - 1][prop]) {spans[position] += 1;spans.push(0);} else {spans.push(1);position = index;}}});tempMap.set(prop, spans);});this.spanMap = tempMap;
},
// 合并方法
changeSpanMethod({column,rowIndex
}) {const spanConfig = this.spanConfig;const config = spanConfig.find(item => item === column.property);if (!config) return {rowspan: 1,colspan: 1};const spans = this.spanMap.get(config);if (!spans) return {rowspan: 1,colspan: 1};return {rowspan: spans[rowIndex],colspan: spans[rowIndex] > 0 ? 1 : 0};
}
方法(函数)执行
// 注:一下两个方法执行顺序不能颠倒
// 排序方法执行(如果不需要排序,那就不用执行排序方法)
this.groupByKeys(['name', 'amount3']);
// 计算合并行方法执行
this.calculateSpans();