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.clientHeight
  const usedHeight = searchFormHeight.value + 
                    tableHeaderHeight.value + 
                    paginationHeight.value + 
                    dynamicHeightOffset

  return Math.max(200, documentHeight - usedHeight) // 确保最小高度为200px
})

尺寸监听器设置

/** 设置尺寸监听器 */
const setupResizeObserver = () => {
  if (!enableDynamicHeight) return

  resizeObserver = new ResizeObserver((entries) => {
    entries.forEach((entry) => {
      const target = entry.target as HTMLElement
      const height = target.offsetHeight

      if (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.value
    resizeObserver.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-expressions
    tableMaxHeight.value
    console.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-pagination
      ref="pagina
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好奇的候选人面向对象

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值