Web前端之Vue+Element实现表格动态不同列合并多行、localeCompare、forEach、table、push、sort、Map


效果图


公共数据

Html

html 复制代码
<el-table :data="tableData" :span-method="changeSpanMethod" border
	style="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

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()

数据未排序时(需要合并的行数据未处于相邻位置)

javascript 复制代码
// 排序方法
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;
}

固定合并行(写死)

javascript 复制代码
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
			};
		}
	}
}

动态合并行

javascript 复制代码
// 合并行数计算
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
	};
}

方法(函数)执行

javascript 复制代码
// 注:一下两个方法执行顺序不能颠倒
// 排序方法执行(如果不需要排序,那就不用执行排序方法)
this.groupByKeys(['name', 'amount3']);
// 计算合并行方法执行
this.calculateSpans();
相关推荐
前端开发与ui设计的老司机12 分钟前
UI前端与数字孪生结合实践探索:智慧物流的货物追踪与配送优化
前端·ui
全能打工人15 分钟前
前端查询条件加密传输方案(SM2加解密)
前端·sm2前端加密
海天胜景36 分钟前
vue3 获取选中的el-table行数据
javascript·vue.js·elementui
翻滚吧键盘1 小时前
vue绑定一个返回对象的计算属性
前端·javascript·vue.js
苦夏木禾1 小时前
js请求避免缓存的三种方式
开发语言·javascript·缓存
超级土豆粉1 小时前
Turndown.js: 优雅地将 HTML 转换为 Markdown
开发语言·javascript·html
秃了也弱了。1 小时前
Chrome谷歌浏览器插件ModHeader,修改请求头,开发神器
前端·chrome
乆夨(jiuze)2 小时前
记录H5内嵌到flutter App的一个问题,引发后面使用fastClick,引发后面input输入框单击无效问题。。。
前端·javascript·vue.js
忧郁的蛋~2 小时前
HTML表格导出为Excel文件的实现方案
前端·html·excel
小彭努力中2 小时前
141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示
前端·javascript·vue.js·交互