页面表格高度自适应

前言

  • 现在后端管理系统主页面基本都是由三部分组成
    • 查询条件,高度不固定,可能有的页面查询条件多,有的少
    • 表格,高度不固定,占据页面剩余高度
    • 分页,高度固定
  • 这三部分加起来肯定是占满全屏的,那么我们可以结合flex布局,来实现。

代码及效果

app.vue

  • 相当于页面首页
<template>
	<div id="app">
		<!-- 假设为页头内容,导航等...-->
		<div class="routers">
			<router-link :to="item.path" v-for="item in routerLinks" :key="item.name">{{ item.name }}</router-link>
		</div>
		<!-- 内容区域 -->
		<div class="content">
			<router-view />
		</div>
	</div>
</template>
<script>
export default {
	data() {
		return {
			routerLinks: [],
		};
	},
	created() {
		this.handleRouterLink();
	},
	methods: {
		handleRouterLink() {
			// 获取所有路由配置
			this.routerLinks = this.$router.getRoutes();
		},
	},
};
</script>

<style lang="scss" scoped>
#app {
	height: 100vh;
	display: flex;
	flex-direction: column;
}
.routers {
	display: flex;
	justify-content: space-around;
}
/* 确定内容高度,好让业务组件的 height:100%生效 */
.content {
	flex: 1;
}
</style>

test.vue

  • 某业务表格组件
<!-- 表格高度自适应 -->
<template>
	<div class="wrapper">
		<!-- 查询条件 -->
		<div class="searchView">
			<div class="formItem" v-for="(item, index) in formNum" :key="index"></div>
		</div>
		<!-- 表格 -->
		<div class="tableView" :key="tableKey">
			<el-table :data="tableData" ref="myTable" style="width: 100%" :height="tableHeight">
				<el-table-column prop="date" label="日期" width="180"> </el-table-column>
				<el-table-column prop="name" label="姓名" width="180"> </el-table-column>
				<el-table-column prop="address" label="地址"> </el-table-column>
			</el-table>
		</div>
		<!-- 分页 -->
		<div class="pageView">
			<el-pagination
				:pager-count="5"
				@size-change="handleSizeChange"
				@current-change="handleCurrentChange"
				:current-page.sync="currentPage2"
				:page-sizes="[100, 200, 300, 400]"
				:page-size="100"
				layout="sizes, prev, pager, next"
				:total="1000"
			>
			</el-pagination>
		</div>
	</div>
</template>
<script>
export default {
	data() {
		return {
			// 表格key,当表格height变化时,el-table无法重新渲染,只能刷新key,强制渲染表格组件
			tableKey: 0,

			// 当前页数
			currentPage2: 1,

			// 查询条件数量
			formNum: 4,

			// 表格高度
			tableHeight: 500,

			// 表格数据
			tableData: [
				{
					date: '2016-05-02',
					name: '王小虎',
					address: '上海市普陀区金沙江路 1518 弄',
				},
				{
					date: '2016-05-04',
					name: '王小虎',
					address: '上海市普陀区金沙江路 1517 弄',
				},
				{
					date: '2016-05-01',
					name: '王小虎',
					address: '上海市普陀区金沙江路 1519 弄',
				},
				{
					date: '2016-05-03',
					name: '王小虎',
					address: '上海市普陀区金沙江路 1516 弄',
				},
			],
		};
	},

	async mounted() {
		this.handleTableHeight();

        // 当浏览器大小修改时,同时动态修改表格高度
		window.onresize = this.getDebounce(this.handleTableHeight, 500);
	},
	methods: {
		// 处理表格高度修改事件
		async handleTableHeight() {
			this.tableHeight = 0;
			await this.$nextTick();
			const tableView = document.querySelector('.tableView');
			this.tableHeight = tableView.clientHeight;
			console.log('tableHeight', this.tableHeight);
			this.tableKey++;
		},

		handleSizeChange(val) {
			console.log(`每页 ${val}`);
		},
		handleCurrentChange(val) {
			console.log(`当前页: ${val}`);
		},

		// 生成一个debounce函数,避免事件频繁除法
		getDebounce(func, delay) {
			let timer = null;
			return function (...args) {
				if (timer) {
					clearTimeout(timer);
				}
				timer = setTimeout(() => {
					func.apply(this, args);
				}, delay);
			};
		},
	},
};
</script>
<style lang="scss" scoped>
/* 以下样式皆可写到全局文件中,每个页面布局基本一致 */
.wrapper {
	display: flex;
	flex-direction: column;
	height: 100%;
	.searchView {
		display: flex;
		flex-wrap: wrap;
		gap: 10px 20px;
		.formItem {
			width: 230px;
			height: 30px;
			border: 1px solid #000;
		}
	}

	.tableView {
		flex: 1;
	}
}
</style>

效果

在这里插入图片描述

思路

  • 首先整个内容主页面.wrapper肯定是flex,并且纵向布局,高度100%。
  • 其次,我们要分别在查询条件、表格、分页外层套一层div,这样好进行样式管理。
  • 内容主页面肯定主要展示的是表格,那么我们就给表格外层的divtableView设置flex: 1;,占据剩余所有高度
  • 当页面加载完成的时候,由于是flex布局,表格的高度(剩余高度)就是wrapper的高度100% - searchView的高度 - pageView的高度
  • 然后我们在mounted钩子函数中,获取.tableViewdiv的clientHeight高度,这个值,就能作为表格的高度了。
  • 最后我们把这个高度值赋值给表格el-table的height属性,并且刷新key,强制表格重新渲染以达到效果。
  • 最最后,我们给window.onresize绑定了事件,并且优化了使用防抖,当浏览器大小修改的时候,页面也会动态自适应高度。