需求:
- 用户进入页面时,要设置一下内容区域中表格默认条数和表格最大高度;
- 当容器高度变化时,表格的最大高度也需要修改(比如从大屏拖到笔记本)
环境:vue3+ts+elementplus
因为页面表格都需要,所以封装成一个方法,以下是utils/watchContainerHeight.ts
代码:
数据必须使用
Ref
定义,不然不会是响应式的!!!
注意:在页面调用时,优先于其他生命周期!!!
说明:搜索项会做响应式,所以这个表格高度是会受到影响的,两个场景解决亲测有效~
场景一
场景描述
内容区域界面布局采用的是两个card,参照下图(其中第二个crad的按钮区域可有可有,两种情况都会考虑)
解决方案
主要函数代码如下:
import { onMounted, onBeforeUnmount, Ref } from 'vue';
import type { CardInstance } from 'element-plus';
// 监听列表card高度,从而计算表格最大高度并设置默认条数
export function useTableDynamicHeight(
listCardRef: Ref<CardInstance | null>,
maxHeightRef: Ref<number>,
pageSizeRef: Ref<number>
) {
const watchHeight = () => {
if (listCardRef.value) {
const tableHeight = listCardRef.value?.$el.offsetHeight;
// 判断界面是否有主操作按钮 -- 界面必须使用同一套样式
if (listCardRef.value?.$el.querySelector('.operate-btns')) { // 类名看自己项目定义
// card上下内边距48,按钮区域:32,分页:32
// 至于46和23,猜测是margin或padding,不减这个会压着分页组件,感兴趣的话可以看看是什么
maxHeightRef.value = tableHeight - (48 + 64 + 46);
} else {
maxHeightRef.value = tableHeight - (48 + 32 + 23);
}
}
};
onMounted(() => {
window.addEventListener('resize', watchHeight);
if (listCardRef.value) {
watchHeight()
// 看项目需求调整
if (maxHeightRef.value < 600) {
pageSizeRef.value = 10;
} else {
pageSizeRef.value = 20;
}
}
});
onBeforeUnmount(() => {
window.removeEventListener('resize', watchHeight);
});
}
页面调用:
<template>
<div class="list-container">
<el-card class="search-card">
<!-- 搜索项和按钮 -->
</el-card>
<el-card class="list-card" ref="listCardRef">
<!-- 也可以没有操作按钮 -->
<div class="operate-btns">
<el-button type="primary">新增</el-button>
</div>
<div class="table-box">
<el-table border :data="tableData" style="width: 100%" row-key="id" header-align='center'
:default-expand-all="false" empty-text="暂无数据" :max-height="maxHeight">
<!-- 列 -->
</el-table-column>
</el-table>
<div class="pagination"></div>
</div>
</el-card>
</div>
<router-view />
</template>
<script setup lang="ts">
import { reactive, ref, onMounted } from "vue";
// 1. 引入方法和card类型
import type { CardInstance } from "element-plus"
import { useTableDynamicHeight } from '@/utils/watchContainerHeight'
// 2. 定义所需变量
const tableData = ref([])
const maxHeight = ref() // 表格最大高度
const currentPage = ref(1); // 当前页
const pageSize = ref(10); // 每页显示的条数
const listCardRef = ref<CardInstance | null>(null)
// 3. 调用方法
useTableDynamicHeight(listCardRef, maxHeight, pageSize) // 在onMounted方法上面!!!
onMounted(() => {});
</script>
<style scoped lang="less"></style>
场景二
场景描述
适用于搜索和表格在同一个crad里面,中间使用分割线区分
import { onMounted, onBeforeUnmount, Ref } from 'vue';
export function useContainerHeight(
containerRef: Ref<HTMLElement | null>,
searchFormRef: Ref<HTMLElement | null>,
maxHeightRef: Ref<number>,
pageSizeRef: Ref<number>
) {
const watchHeight = () => {
if (containerRef.value && searchFormRef.value) {
const height = containerRef.value.offsetHeight;
const searchHeight = searchFormRef.value.offsetHeight;
if (containerRef.value?.querySelector('.operate-btns')) {
maxHeightRef.value = height - 48 - searchHeight - 48 - 64 - 46;
} else {
maxHeightRef.value = height - 48 - searchHeight - 48 - 64;
}
}
};
onMounted(() => {
window.addEventListener('resize', watchHeight);
if (containerRef.value && searchFormRef.value) {
watchHeight()
// 可以根据项目需求自己设置,如果需要高度变化,默认条数也变,可以把下面这段逻辑加到watchHeight中
if (maxHeightRef.value < 600) {
pageSizeRef.value = 10;
} else {
pageSizeRef.value = 20;
}
}
});
onBeforeUnmount(() => {
window.removeEventListener('resize', watchHeight);
});
}
页面调用:
<template>
<div class="container" ref="container">
<div ref='searchRef'>搜索区</div>
<el-divider />
/** 页面其他逻辑,只写到了需要的参数,其他参数根据官网和需求自己加哦~ **/
<el-table :max-height="maxHeight">
</el-table>
<el-pagination v-model:page-size="pageSize" :background="true" />
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useContainerHeight } from '@/utils/watchContainerHeight'
const currentPage = ref(1); // 当前页
const pageSize = ref(10); // 每页显示的条数
const container = ref<HTMLElement | null>(null)
const searchRef= ref<HTMLElement | null>(null)
useContainerHeight(container, searchRef, maxHeight, pageSize) // 优先于其他生命周期
onMounted(()=>{})
</script>