0
点赞
收藏
分享

微信扫一扫

vue3+el-table表格表头增加斜线

芷兮离离 2022-01-26 阅读 42

1.需求
类似excel可以加斜线有双表头,如下图(咱们当时一整个难住,咱们裙裙难受)
在这里插入图片描述

2.咱们开始面向百度,找到一个好主意!
上链接
3.可能会有多级表头所有把table封装了一下,所以我没有用插槽来处理斜线,直接用到了多级表头

//表格组件
<template>
	<div id="bias-table">
		<el-table
			ref="table"
			v-loading="props.tableConfig.tableLoading"
			:data="props.tableData"
			:max-height="props.tableConfig.maxHeight || maxHeight"
			:show-summary="props.tableConfig.showSummary"
			:header-cell-style="methods.handleHeaderCell"
		>
			<!--我们当时还有一个需求,表格的列是动态的渲染的,所以一定要保证key值的唯一-->
			<column-component
				v-for="th in props.columnConfig"
				:key="th.id"
				:column="th"
			></column-component>
		</el-table>
		<div
			class="line"
			v-if="!props.tableConfig.standard"
			:style="{
				width: lineWhide + 'px',
				transform: 'rotate(' + lineDeg + 'deg)',
			}"
		></div>
	</div>
</template>
<script setup>
import { defineProps } from 'vue';
import { ref, onMounted, nextTick } from 'vue';
import columnComponent from './column.vue';
const props = defineProps({
	tableData: {
		type: Array,
		default: () => [],
	},
	tableConfig: {
		type: Object,
		default: () => {
			return {
				tableLoading: false,
				standard: false,
				showSummary: true,
			};
		},
	},
	columnConfig: {
		type: Array,
		default: () => [],
	},
});
//自定义数据data
const maxHeight = ref(0);
const table = ref(null);
const firstCellClassName = ref(''); //第一个单元格的类名
const firstCellWidth = ref(); //第一个单元格的宽度
const firstCellHeight = ref(0); //第一个单元格的高度
const lineWhide = ref(0); //对角线的宽度
const lineDeg = ref(0); //对角线的角度
onMounted(() => {
	nextTick(() => {
		// maxHeight.value = window.innerHeight - table.value.$el.offsetTop - 252;
		maxHeight.value = window.innerHeight - table.value.$el.offsetTop;
		// console.log(maxHeight.value, '最大高度');
	});
});
const methods = {
	/**
	 * 设置表头第一个单元格对角线
	 * @function
	 */
	handleHeaderCell({ row, column, rowIndex, columIndex }) {
		//如果使用的多级表头  就需要判断是第几个表头
		if (rowIndex === 0) {
			nextTick(() => {
				//根据id设置第一个单元格的class类名
				firstCellClassName.value = row[0].id;
				//获取第一个单元格的宽度,原文说用realWidth,但我获取不到,所以用到了width,目前没出错
				firstCellWidth.value = row[0].width;
				methods.getElement();
				// console.log(firstCellWidth.value, '查看宽度');
			});
		}
	},
	getElement() {
		//用原生获取第一个单元格的高度
		let element = document.getElementsByClassName(firstCellClassName.value)[0];
		//我用到的是复合表头,并且高度相同,所以这里的高度是二倍的
		firstCellHeight.value = 2 * element.offsetHeight;
		// console.log(firstCellHeight.value, '查看高度');
		//获取对角线的长度 a²+b²=c²
		lineWhide.value = Math.sqrt(
			firstCellWidth.value * firstCellWidth.value +
				firstCellHeight.value * firstCellHeight.value,
		);
		// console.log(lineWhide.value, '对角线宽度');
		//获取对角线旋转的角度
		lineDeg.value =
			(Math.atan(firstCellHeight.value / firstCellWidth.value) * 180) / Math.PI;
		// console.log(lineDeg.value, '角度');
	},
};
</script>
<style lang="scss" scoped>
#bias-table {
	position: relative;
	.line {
		position: absolute;
		z-index: 9;
		top: 0;
		left: 0;
		height: 1px;
		background-color: #ccc;
		transform-origin: left;
	}
	:deep .el-table {
		tr {
			height: 20px;
		}
		thead.is-group > tr:first-child > th:first-child {
			text-align: right;
			padding: 0;
			border-bottom: 0px;
		}
		thead.is-group > tr:nth-child(2) > th:first-child {
			text-align: left;
			padding: 0;
		}
		/*实现表格头数据换行*/
		.cell {
			/*text-align: center;*/
			white-space: pre-line; /*保留换行符*/
		}
	}
}
</style>

4.column组件封装

<template>
	<el-table-column
		:label="props.column.label"
		:prop="props.column.prop"
		:align="props.column.align || 'center'"
		:width="props.column.width"
		:show-overflow-tooltip="props.column.tooltip || true"
	>
		<template v-if="props.column.children && props.column.children.length">
			<column-component
				v-for="item in props.column.children"
				:key="item.id"
				:column="item"
			></column-component>
		</template>
		<!--这里不可以用v-else-->
		<template v-if="!props.column.children" #default="scope">
			<span>{{ scope.row[props.column.prop] }}</span>
		</template>
	</el-table-column>
</template>
<script setup>
import columnComponent from './column';
import { defineProps } from 'vue';
import { ref, onMounted, nextTick } from 'vue';
const props = defineProps({
	column: {
		type: Object,
		default: () => {},
	},
});
onMounted(() => {});
const methods = {};
</script>

5.如果有好的方案请告诉我,持续学习!

举报

相关推荐

0 条评论