Vue 3 + Element Plus 动态表格高度自适应方案详解
在数据密集的中后台系统中,表格往往需要展示大量数据。固定高度的表格在不同屏幕尺寸下体验不佳,而动态自适应的表格高度能显著提升用户体验。本文将深入解析基于 Vue 3 和 Element Plus 的表格动态高度自适应方案。
🎯 需求背景
在传统的前端开发中,表格高度通常采用以下方式:
-
❌ 固定高度:在不同分辨率下显示不一致
-
❌ 百分比高度:受父容器限制,计算复杂
-
❌ 最大高度:需要手动调整,不够灵活
理想方案:表格能够根据浏览器窗口大小、搜索区域高度、分页组件高度等动态元素自动计算可用高度,实现真正的自适应。
🛠 核心实现原理
1. 高度计算模型
表格可用高度 = 窗口高度 - (搜索区域高度 + 表头高度 + 分页区域高度 + 预留偏移量)
2. 技术关键点
-
ResizeObserver API:监听DOM元素尺寸变化
-
Composition API:响应式数据驱动
-
nextTick:确保DOM更新后获取准确尺寸
📁 核心代码解析
动态高度计算
// 计算表格最大高度
const tableMaxHeight = computed(() => {if (!enableDynamicHeight) {return undefined}const documentHeight = document.documentElement.clientHeightconst usedHeight = searchFormHeight.value + tableHeaderHeight.value + paginationHeight.value + dynamicHeightOffsetreturn Math.max(200, documentHeight - usedHeight) // 确保最小高度为200px
})
尺寸监听器设置
/** 设置尺寸监听器 */
const setupResizeObserver = () => {if (!enableDynamicHeight) returnresizeObserver = new ResizeObserver((entries) => {entries.forEach((entry) => {const target = entry.target as HTMLElementconst height = target.offsetHeightif (target === searchFormRef.value?.$el || target === searchFormRef.value) {searchFormHeight.value = showSearch.value ? height : 0} else if (target === tableHeaderRef.value?.$el) {tableHeaderHeight.value = height} else if (target === paginationRef.value?.$el) {paginationHeight.value = total.value > 0 ? height : 0}})})// 观察相关元素if (searchFormRef.value) {const searchFormEl = searchFormRef.value.$el || searchFormRef.valueresizeObserver.observe(searchFormEl)}if (tableHeaderRef.value) {resizeObserver.observe(tableHeaderRef.value.$el)}if (paginationRef.value) {resizeObserver.observe(paginationRef.value.$el)}
}
窗口 resize 事件处理
/** 监听窗口大小变化 */
const handleResize = () => {// 触发重新计算if (enableDynamicHeight) {// eslint-disable-next-line ts/no-unused-expressionstableMaxHeight.valueconsole.warn(document.documentElement.clientHeight, tableMaxHeight.value, '005')}
}
🚀 使用方法
1. 启用动态高度
const {tableMaxHeight,searchFormRef,paginationRef,tableHeaderRef,// ... 其他返回值
} = useTableOperations({// ... 其他配置enableDynamicHeight: true, // 启用动态高度dynamicHeightOffset: 260, // 自定义偏移量
})
2. 模板中绑定 ref
<template><div><!-- 搜索表单 - 绑定 searchFormRef --><el-form ref="searchFormRef" :model="queryParams" v-show="showSearch"><!-- 表单项 --></el-form><!-- 表格 - 绑定 max-height 和 tableHeaderRef --><el-table:data="dataList":max-height="tableMaxHeight"ref="tableHeaderRef"><!-- 表格列 --></el-table><!-- 分页 - 绑定 paginationRef --><el-paginationref="pagina