Skip to content

useTableHeight

表格高度自适应组合函数,基于 Vue Composition API 实现表格高度的自适应计算和响应式管理。

📋 功能特性

  • 高度计算: 动态计算表格的最佳高度,确保内容完整显示
  • 响应式调整: 响应窗口大小、侧边栏状态、页签配置和表单显示状态变化
  • 防抖处理: 避免短时间内重复计算表格高度
  • 生命周期管理: 自动添加和移除事件监听器
  • 搜索表单管理: 提供表单引用和显示状态控制
  • 高度调整: 支持自定义高度调整值

🎯 基础用法

基本使用

vue
<template>
  <div class="table-container">
    <!-- 搜索表单 -->
    <el-form ref="queryFormRef" v-show="showSearch">
      <el-form-item>
        <el-input placeholder="搜索关键词" />
      </el-form-item>
    </el-form>
    
    <!-- 工具栏 -->
    <div class="toolbar">
      <el-button @click="showSearch = !showSearch">
        {{ showSearch ? '隐藏' : '显示' }}搜索
      </el-button>
    </div>
    
    <!-- 表格 -->
    <el-table 
      :data="tableData" 
      :height="tableHeight"
      style="width: 100%"
    >
      <el-table-column prop="name" label="姓名" />
      <el-table-column prop="age" label="年龄" />
    </el-table>
    
    <!-- 分页 -->
    <el-pagination
      v-model:current-page="currentPage"
      :total="total"
    />
  </div>
</template>

<script setup>
import { useTableHeight } from '@/composables/useTableHeight'

const { tableHeight, queryFormRef, showSearch } = useTableHeight()

const tableData = ref([
  { name: '张三', age: 25 },
  { name: '李四', age: 30 }
])

const currentPage = ref(1)
const total = ref(100)
</script>

带高度调整参数

vue
<template>
  <div class="custom-table">
    <!-- 自定义头部区域,需要额外减去80px高度 -->
    <div class="custom-header" style="height: 80px;">
      自定义头部内容
    </div>
    
    <el-form ref="queryFormRef" v-show="showSearch">
      <!-- 表单内容 -->
    </el-form>
    
    <el-table :height="tableHeight" :data="tableData">
      <!-- 表格列 -->
    </el-table>
  </div>
</template>

<script setup>
// 传入80,表示需要额外减去80px高度
const { tableHeight, queryFormRef, showSearch } = useTableHeight(80)
</script>

🔧 API 参考

函数签名

typescript
useTableHeight(heightAdjustment?: number): {
  tableHeight: Ref<number>
  queryFormRef: Ref<any>
  calculateTableHeight: () => Promise<void>
  showSearch: Ref<boolean>
}

参数

参数类型默认值说明
heightAdjustmentnumber0高度调整值,正数减少高度,负数增加高度

返回值

属性类型说明
tableHeightRef<number>计算后的表格高度
queryFormRefRef<any>查询表单的引用,用于获取表单高度
calculateTableHeightFunction手动触发高度计算的方法
showSearchRef<boolean>搜索表单的显示状态

💡 高级用法

手动重新计算高度

vue
<script setup>
const { tableHeight, calculateTableHeight } = useTableHeight()

// 在某些动态内容变化后手动重新计算
const onContentChanged = async () => {
  await nextTick()
  await calculateTableHeight()
}
</script>

监听高度变化

vue
<script setup>
const { tableHeight } = useTableHeight()

// 监听表格高度变化
watch(tableHeight, (newHeight) => {
  console.log('表格高度变化:', newHeight)
})
</script>

结合其他组件

vue
<template>
  <el-card>
    <template #header>
      <div class="card-header">
        <span>用户列表</span>
        <el-button @click="showSearch = !showSearch">
          切换搜索
        </el-button>
      </div>
    </template>
    
    <!-- 查询表单 -->
    <el-form ref="queryFormRef" v-show="showSearch" inline>
      <el-form-item label="用户名">
        <el-input v-model="queryForm.username" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary">查询</el-button>
        <el-button>重置</el-button>
      </el-form-item>
    </el-form>
    
    <!-- 表格 -->
    <el-table 
      :data="tableData" 
      :height="tableHeight"
      border
      stripe
    >
      <el-table-column type="selection" width="55" />
      <el-table-column prop="username" label="用户名" />
      <el-table-column prop="email" label="邮箱" />
      <el-table-column prop="status" label="状态">
        <template #default="scope">
          <el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
            {{ scope.row.status === 1 ? '启用' : '禁用' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="180">
        <template #default="scope">
          <el-button size="small" @click="handleEdit(scope.row)">
            编辑
          </el-button>
          <el-button size="small" type="danger" @click="handleDelete(scope.row)">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    
    <!-- 分页 -->
    <el-pagination
      v-model:current-page="pagination.current"
      v-model:page-size="pagination.size"
      :page-sizes="[10, 20, 50, 100]"
      :total="pagination.total"
      layout="total, sizes, prev, pager, next, jumper"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </el-card>
</template>

<script setup>
import { useTableHeight } from '@/composables/useTableHeight'

// 使用表格高度自适应,card 头部需要额外减去一些高度
const { tableHeight, queryFormRef, showSearch } = useTableHeight(20)

const queryForm = ref({
  username: ''
})

const tableData = ref([])
const pagination = ref({
  current: 1,
  size: 20,
  total: 0
})

const handleEdit = (row) => {
  console.log('编辑', row)
}

const handleDelete = (row) => {
  console.log('删除', row)
}

const handleSizeChange = (size) => {
  pagination.value.size = size
  // 重新加载数据
}

const handleCurrentChange = (current) => {
  pagination.value.current = current
  // 重新加载数据
}
</script>

⚠️ 注意事项

1. 查询表单引用

确保将 queryFormRef 正确绑定到查询表单组件:

vue
<el-form ref="queryFormRef" v-show="showSearch">
  <!-- 表单内容 -->
</el-form>

2. 高度调整参数

heightAdjustment 参数的含义:

  • 正数: 减少表格高度(当页面有额外元素占用空间时)
  • 负数: 增加表格高度(当页面元素比预期少时)
  • 0: 使用默认计算逻辑

3. 响应式变化

组合函数会自动监听以下变化:

  • 窗口大小变化
  • 侧边栏展开/收起
  • 页签显示/隐藏配置
  • 搜索表单显示/隐藏

4. 防抖处理

高度计算使用了防抖处理,避免频繁触发:

  • 窗口调整: 150ms 延迟
  • 侧边栏变化: 240ms 延迟(等待动画完成)
  • 其他变化: 100ms 延迟

🎨 样式建议

css
.table-container {
  padding: 16px;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.toolbar {
  margin-bottom: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.el-pagination {
  margin-top: 16px;
  text-align: right;
}

通过使用 useTableHeight,可以让表格在不同屏幕尺寸和布局变化下都能保持最佳的显示效果。