实现表格动态高度的滚动,技术基于Element plus + vue3.0 + vite + ts
方案一:
方案一关键实现代码
<div ref="container">
<el-form id="queryForm"></el-form>
<el-table :height="tableHeight"></el-table>
</div>
<script setup lang="ts">
import { reactive,ref,toRefs } from 'vue';
const state = reactive({
tableHeight:500,
})
const { tableHeight } toRefs
// 获取表格高度
function getTableHeight() {
let queryFormHeight = document.getElementById('queryForm')?.clientHeight as number;//搜索重置Form的高度
let containerHeight = container.value?.clientHeight as number;//局部路由视图容器高度
state.tableHeight = containerHeight - queryFormHeight - 24 - 68 - 40;//路由视图高度-Form高度-padding-分页-新建修改删除等的高度
}
</script>
咋一看这样的实现方案有点low,不通用,每个文件考来考去的,看下面一种,方案二
实现效果
方案二:
第一步,封装一个通用全局组件:
<template>
<div class="app-operation-brand" ref="refBrand">
<slot></slot>
</div>
</template>
<script lang='ts'>
// 添加名称用于缓存页面数据
export default { name: 'AppOperationBrand'}
</script>
<script lang='ts' setup>
// 动态计算数据显示区高度
import { ref } from 'vue';
import refHeightHooks from '@/hooks/refHeight';
const refBrand = ref<HTMLDivElement | null>(null);
const emits = defineEmits(['getTabHeightFn'])
const props = defineProps({
pagination: {
type: Boolean,
required: false,
default: false
},
elNextHeight: {//其他dom的时候,计算好了高度然后传进来
type: Number,
required: false,
default: 0
}
})
refHeightHooks({el: refBrand, pagination: props.pagination,elNextHeight:props.elNextHeight}).then(res => {
if (props.pagination) {
const { baseHeight, optionHeight, pagHeight } = res;
emits('getTabHeightFn', {baseHeight, optionHeight, pagHeight});
//无分页高度表体高度(不含菜单栏,边框,顶部),Form or 其它元素高度,有分页表体高度
} else {
const { baseHeight, optionHeight } = res;
emits('getTabHeightFn', { baseHeight, optionHeight });
//无分页高度表体高度(不含菜单栏,边框,顶部),Form or 其它元素高度
}
});
</script>
第二部,封装全局组件用到的hooks中方法refHeightHooks
/**
* 用于计算数据显示区域可滚动区间高度
*/
/**
* 用于计算数据显示区域可滚动区间高度
*/
import { onMounted } from 'vue'
type Options = {
el: any, // 只有一个dom的时候
pagination: boolean, // 是否有分页组件
elNextHeight?: number // 其他dom的时候,计算好了高度然后传进来
}
export default function (option: Options): Promise<any> {
return new Promise((resolve) => {
onMounted(() => {
let baseHeight = 500; // 默认高度
const optionHeight = option.el.value.offsetHeight;
baseHeight = document.body.offsetHeight - optionHeight - 184; // 顶部高度 + 菜单栏高度 + 边框 = 204
baseHeight = option.elNextHeight ? baseHeight - option.elNextHeight : baseHeight;
let pagHeight = baseHeight;
if (option.pagination) {
pagHeight = baseHeight - 68; // 分页组件默认68高度
return resolve({ baseHeight, optionHeight, pagHeight })//无分页高度表体高度(不含菜单栏,边框,顶部),Form or 其它元素高度,有分页表体高度
} else {
return resolve({ baseHeight, optionHeight })
}
})
})
}
第三步,挂载到全局,在main.js中如下操作:
//引入
import AppOperationBrand from '@/components/AppOperationBrand/index.vue'
// 注册全局组件
app
.component('AppOperationBrand', AppOperationBrand)
.mount('#app');
第四步,在界面的Form上包裹上这么一层组件
<template>
<app-operation-brand @getTabHeightFn="getTabHeightFn" :pagination="true" :elNextHeight="24">
<el-form ref="queryRef">
</el-form>
</app-operation-brand>
<el-table :max-height="pHeight"></el-table>
<template>
<script lang="ts" setup>
import { ref } from 'vue'
// 计算数据列表高度
const pHeight = ref(0);
function getTabHeightFn(data: heightData) {
pHeight.value = data.baseHeight as number;
}