高级表格:自适应屏幕高度及加载过滤效果实现
概述
在需求分析基础上,本节实现高级表格的自适应屏幕高度和加载过滤效果。自适应让表格高度随容器动态计算,分页器固定在底部;加载过滤则在数据请求时提供友好的视觉反馈。
自适应高度实现
核心思路
通过 useResizeObserver 监听容器尺寸变化,动态计算表格可用高度:
// composables/useAdaptiveTable.ts
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { useResizeObserver } from '@vueuse/core'
interface UseAdaptiveTableOptions {
headerHeight?: number // 搜索表单高度
paginationHeight?: number // 分页器高度
padding?: number // 内边距
}
export function useAdaptiveTable(
containerRef: Ref<HTMLElement | undefined>,
options: UseAdaptiveTableOptions = {}
) {
const { headerHeight = 60, paginationHeight = 50, padding = 32 } = options
const tableHeight = ref<number>(400)
useResizeObserver(containerRef, ([entry]) => {
const containerHeight = entry.contentRect.height
tableHeight.value = containerHeight - headerHeight - paginationHeight - padding
})
return { tableHeight }
}
typescript
模板使用
<template>
<div ref="containerRef" class="table-container">
<!-- 搜索表单 -->
<SearchForm />
<!-- 自适应表格 -->
<el-table
:height="tableHeight"
:data="tableData"
v-loading="loading"
>
<el-table-column prop="name" label="名称" />
<el-table-column prop="date" label="日期" />
<!-- 更多列... -->
</el-table>
<!-- 分页器 -->
<el-pagination
v-model:current-page="page"
v-model:page-size="pageSize"
:total="total"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useAdaptiveTable } from '@/composables/useAdaptiveTable'
const containerRef = ref<HTMLElement>()
const { tableHeight } = useAdaptiveTable(containerRef)
</script>
vue
加载过滤效果
Loading 状态
使用 Element Plus 的 v-loading 指令在数据请求期间展示加载动画:
const loading = ref(false)
async function fetchData() {
loading.value = true
try {
const { data } = await api.getTableList(queryParams)
tableData.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
typescript
空数据状态
<el-table :data="tableData" v-loading="loading">
<template #empty>
<el-empty description="暂无数据">
<el-button type="primary" @click="fetchData">重新加载</el-button>
</el-empty>
</template>
</el-table>
vue
骨架屏加载
首次加载时使用骨架屏,翻页时使用 v-loading:
<template>
<!-- 首次加载骨架屏 -->
<el-skeleton v-if="firstLoading" :rows="10" animated />
<!-- 正常表格 -->
<el-table v-else :data="tableData" v-loading="loading">
<!-- columns -->
</el-table>
</template>
vue
自适应 vs 固定高度对比
| 特性 | 自适应模式 | 固定高度 |
|---|---|---|
| 配置方式 | :height="tableHeight" 动态计算 | height="400" 固定值 |
| 分页器 | 固定在容器底部 | 紧跟表格 |
| 响应式 | 窗口大小变化时自动调整 | 不变 |
| 滚动 | 表格内部滚动 | 表格内部滚动 |
| 适用场景 | 管理后台主内容区 | 固定尺寸的弹窗/卡片 |
实践要点
useResizeObserver确保窗口大小变化(如侧边栏折叠)时表格高度自动更新- 搜索表单展开/折叠时,需将表单高度变化纳入计算
calc()方案在某些复杂布局中可能不够精确,JS 动态计算更可靠- 加载状态区分首次加载(骨架屏)和翻页加载(v-loading),提升用户体验
- 表格
height属性必须设置才能启用固定表头和虚拟滚动
↑