table 合并单元格并实现自滚动列表,鼠标移入停止滚动移出恢复滚动,如何处理?

137 阅读1分钟

实现的效果如下:

20230808_105812.gif

具体代码:

	<div class="box tableDiv">
		<el-table :data="tableData" stripe :cell-style="cellStyle" :span-method="objectSpanMethod" ref="datalist"
			@mouseover.native="mouseEnter()" @mouseout.native="mouseLeave()" height="980" border
			:header-cell-style="{background:'#eef1f6',color:'#333'}" style="width: 100%">
			<el-table-column prop="stationCode" label="工站" align="center" min-width="100" />
			<el-table-column prop="stationName" label="工站名称" align="center" min-width="200" />
			<el-table-column prop="completeRate" label="工站进度" align="center" min-width="80">
				<template slot-scope="scope">
					<span>{{ scope.row.completeRate *100 }}%</span>
				</template>
			</el-table-column>
			<el-table-column prop="serialNum" label="序号" align="center" min-width="80" />
			<el-table-column prop="workPlan" label="下达模块工作计划" align="center" min-width="140" />
			<el-table-column prop="num" label="数量" align="center" min-width="60" />
			<el-table-column prop="qualityStatus" label="品质检验" align="center" min-width="80" />
			<el-table-column prop="modelRate" label="模块进度" align="center" min-width="100">
				<template slot-scope="scope">
					<span>{{ scope.row.modelRate *100 }}%</span>
				</template>
			</el-table-column>
			<el-table-column prop="abnormalCause" label="备注" align="center" min-width="220" />
		</el-table>
	</div>
</template>

<script>
	let rolltimmer = "";
	import {
		getUrlParmes
	} from "@/utils/index";
	import {
		reportDesList
	} from "@/network/PdfProgress";
	export default {
		name: "",
		components: {},
		data() {
			return {
				//每次滚动距离
				rollPx: 2,
				//滚动间隔
				rolltime: 50,
				queryParams: {},
				tableData: [],
				spanArr: [], //存储合并单元格的开始位置
				pos: 0,
				timer: null,
				heartbeat: 1000 * 60 * 60, //一小时刷新一次
				// heartbeat: 1000 * 60,//60秒刷新一次
			};
		},
		created() {
			this.gettimeList();
		},
		mounted() {
			this.getList();
		},
		beforeDestroy(){
			console.log('beforeDestroy');
			clearInterval(rolltimmer)
			clearInterval(this.timer);
		},
		destroyed() {
			console.log('destroyed');
			clearInterval(rolltimmer)
			clearInterval(this.timer);
		},
		methods: {
			getList() {
				let that = this;
				this.queryParams = Object.assign(this.queryParams, getUrlParmes());
				reportDesList(this.queryParams).then(response => {
					let datas = response?.data?.rows || {};
					this.getSpanArr(datas);
					this.tableData = [];
					this.tableData = datas;
				}).catch((err) => {
					this.$message.error('workshopScreen/list接口异常' + err.message + err.code);
				})
				setTimeout(() => {
					clearInterval(rolltimmer)
					that.autoRoll();
				}, 200)
			},
			gettimeList() {
				setInterval(() => {
					window.location.reload();
				},this.heartbeat)
				// let that = this;
				// clearInterval(rolltimmer);
				// let num = 0;
				// //创建并执行定时器
				// this.timer = setInterval(() => {
				// 	that.getList();
				// 	console.log('定时器', num);
				// 	//当num等于999时清除定时器 刷新页面  防止爆栈 卡死
				// 	if (num == 999) {
				// 	   window.location.reload();
				// 	}
				// 	num++;
				// }, this.heartbeat);
			},

			//实现滚动核心方法 
			//前置条件 1.table有height 2.show-header不能设置为false 值为false时不能正确活取到scrollHeight 
			autoRoll(stop) {
				if (stop) {
					clearInterval(rolltimmer);
					return;
				}
				const table = this.$refs.datalist;
				const divData = table.bodyWrapper;
				rolltimmer = setInterval(() => {
					divData.scrollTop += this.rollPx;
					if (divData.clientHeight + divData.scrollTop >= divData.scrollHeight) {
						divData.scrollTop = 0;
					}
				}, this.rolltime);
			},
			//鼠标进入 停止滚动
			mouseEnter(time) {
				clearInterval(rolltimmer);
				this.autoRoll(true);
			},
			//鼠标离开 开始滚动
			mouseLeave() {
				clearInterval(rolltimmer);
				this.autoRoll();
			},
			stopScroll() {
				clearInterval(rolltimmer);
			},
			//表格第一列合并之前,元素要并列的行数获取
			getSpanArr(data) {
				for (var i = 0; i < data.length; i++) {
					if (i === 0) {
						this.spanArr.push(1)
						this.pos = 0 //pos是spanArr的索引
					} else {
						// 判断当前元素与上一个元素是否相同  
						if (data[i].stationCode === data[i - 1].stationCode) {
							// 相同的话 就加一 表示合并行数加一  0表示该行不显示
							this.spanArr[this.pos] += 1;
							this.spanArr.push(0);
						} else {
							//不相同就添加一位1 并设置索引位置
							this.spanArr.push(1);
							this.pos = i;
						}
					}
				}
			},
			// 表格第一列合并的代码
			objectSpanMethod({
				row,
				column,
				rowIndex,
				columnIndex
			}) {
				if (columnIndex === 0 || columnIndex === 1 || columnIndex === 2) {
					const _row = this.spanArr[rowIndex];
					const _col = _row > 0 ? 1 : 0;
					// [0,0] 表示这一行不显示, [2,1]表示行的合并数
					return {
						rowspan: _row,
						colspan: _col
					}
				}
			},
			cellStyle({
				row,
				column,
				rowIndex,
				columnIndex
			}) {
				if (columnIndex != -1) {
					return "color:#333 ";
				}
				return "";
			}
		}
	};
</script>

<style scoped>
	.box {
		padding: 100px;
		display: flex;
	}

	.btn-box {
		margin-left: 100px;
		margin-top: 50px;
	}

	.listDiv {
		width: 100%;
		height: 96%;
		display: flex;
		justify-content: center;
		align-items: center;
		margin: 1%;
		position: relative;
		background: url("../img/tbg1.png") no-repeat 50% 50%;
	}

	.tableDiv {
		z-index: 100;
		width: 98%;
		height: 90%;
		pointer-events: auto;
		padding: 0 1%;
		box-shadow: 0 0 1rem #b8b7b780 inset;
		-webkit-backdrop-filter: blur(4px);
		backdrop-filter: blur(4px);
	}

	.tableDiv::before,
	.tableDiv::after {
		content: "";
		pointer-events: none;
		position: absolute;
		width: 1.5rem;
		height: 1.5rem;
		transition: 0.3s ease-in-out;
	}

	.tableDiv::before {
		top: -0.1rem;
		left: -0.1rem;
		border-top: 0.15rem solid #769ce2;
		border-left: 0.15rem solid #769ce2;
	}

	.tableDiv::after {
		right: -0.1rem;
		bottom: -0.1rem;
		border-bottom: 0.15rem solid #769ce2;
		border-right: 0.15rem solid #769ce2;
	}

	.tableDiv:hover::before {
		width: 100%;
		height: 100%;
		border-top: 0.15rem solid #769ce2;
		border-left: 0.15rem solid #769ce2;
		animation: glow_before 1s ease-out infinite alternate;
	}

	.tableDiv:hover::after {
		width: 100%;
		height: 100%;
		border-bottom: 0.15rem solid #769ce2;
		border-right: 0.15rem solid #769ce2;
		animation: glow_after 1s ease-out infinite alternate;
	}

	.tHeaderContainer {
		position: relative;
		height: 2.7rem;
		width: 100%;
		overflow: hidden;
	}

	.scrollContainer {
		position: relative;
		height: calc(100% - 2.7rem);
		min-height: 900px;
		width: 100%;
		overflow: hidden;
	}

	.tHeader,
	.tTableName {
		position: absolute;
		width: 100%;
		height: 100%;
		/* border-collapse属性是运用在table标签里的, collapse值会让 边框合并为一个单一的边框。会忽略 border-spacing 和 empty-cells 属性。 */
		border-collapse: collapse;
	}

	tr {
		height: 2rem;
		font-size: 0.8rem;
		text-align: center;
		border-bottom: 1px dashed rgb(107, 101, 119);
	}

	th {
		font-size: 0.9rem;
		height: 2.5rem;
		width: 11%;
		text-align: center;
	}

	td {
		width: 11%;
		height: 100%;
		text-align: center;
	}

	@font-face {
		font-family: "sysFont";
		src: url("/static/font/时尚中黑简体.ttf");
	}

	@keyframes glow_before {
		0% {
			box-shadow: -0.1rem -0.1rem 0.2rem #408acf50;
		}

		100% {
			box-shadow: -0.5rem -0.5rem 1rem #769ce2;
		}
	}

	@keyframes glow_after {
		0% {
			box-shadow: 0.1rem 0.1rem 0.2rem #408acf50;
		}

		100% {
			box-shadow: 0.5rem 0.5rem 1rem #769ce2;
		}
	}
</style>

20230808_111953.gif

其中 class是tableDiv 的animation: glow_after 1s ease-out infinite alternate; 是鼠标移入移出的呼吸聚焦动画;