高级表格需求分析:自适应高度、行拖拽与列拖拽
概述
本节分析管理后台高级表格的三大核心需求:自适应屏幕高度、行拖拽排序、列拖拽排序。参考 PureAdmin 框架的高级用法,进行需求拆解与原理分析。
需求全景
| 功能 | 描述 | 核心原理 |
|---|---|---|
| 自适应高度 | 表格高度随内容区域自动调整,分页器固定底部 | calc() 计算 + Flex 布局 |
| 行拖拽 | 拖拽表格行调整数据顺序 | SortableJS + DOM 操作 |
| 列拖拽 | 拖拽表头列调整字段顺序 | SortableJS + columns 重排 |
自适应高度
功能表现
- 自适应模式:表格高度自动撑满可用空间,分页器固定在底部
- 默认模式:表格高度由内容决定,分页器紧跟表格
实现思路分析
方案一:Flex 布局(简单但有局限)
.table-container {
display: flex;
flex-direction: column;
height: 100%;
}
.el-table {
flex: 1; /* 自动占满剩余空间 */
}
css
局限:当嵌套层级深时,flex: 1 的继承链容易断裂。
方案二:calc() 动态计算(推荐)
// 根据内容区域实际可用高度计算表格高度
function calcTableHeight() {
const containerHeight = document.querySelector('.content-area')?.clientHeight
const headerHeight = 50 // 搜索表单高度
const pagerHeight = 50 // 分页器高度
const padding = 32 // 内边距
return containerHeight - headerHeight - pagerHeight - padding
}
typescript
<el-table :height="tableHeight" :data="tableData">
<!-- columns -->
</el-table>
<el-pagination />
vue
自适应 vs 默认模式对比
| 维度 | 自适应模式 | 默认模式 |
|---|---|---|
| 表格高度 | 固定(填满容器) | 自适应(由数据量决定) |
| 分页器位置 | 固定底部 | 紧跟表格 |
| 滚动行为 | 表格内部滚动 | 页面整体滚动 |
| 适用场景 | 数据量大、需固定分页 | 数据量少、列表简短 |
行拖拽
功能表现
- 左侧出现拖拽手柄
- 拖拽行到目标位置后,数据数组重新排序
- 支持通过属性配置开启/关闭
配置设计
interface TableProps {
// ...
draggable?: boolean | { row?: boolean; col?: boolean }
}
// 使用方式
<DataTable :draggable="{ row: true }" @row-drop="onRowDrop" />
typescript
实现原理
使用 SortableJS 库绑定到表格的 <tbody> 元素:
import Sortable from 'sortablejs'
function initRowDrag(tableEl: HTMLElement) {
const tbody = tableEl.querySelector('.el-table__body-wrapper tbody')
if (!tbody) return
Sortable.create(tbody, {
animation: 150,
handle: '.drag-handle', // 拖拽手柄选择器
onEnd({ oldIndex, newIndex }) {
// 数据重排
const item = tableData.splice(oldIndex!, 1)[0]
tableData.splice(newIndex!, 0, item)
},
})
}
typescript
列拖拽
功能表现
- 拖拽表头列调整字段顺序
- 列的位置交换后,对应的 columns 配置同步更新
- 与行拖拽同为属性配置控制
实现原理
绑定到表格的 <thead> 元素:
function initColDrag(tableEl: HTMLElement) {
const headerTr = tableEl.querySelector('.el-table__header-wrapper tr')
if (!headerTr) return
Sortable.create(headerTr, {
animation: 150,
onEnd({ oldIndex, newIndex }) {
// columns 重排
const col = columns.value.splice(oldIndex!, 1)[0]
columns.value.splice(newIndex!, 0, col)
},
})
}
typescript
实践要点
- 自适应高度需要考虑搜索表单折叠/展开时的高度变化,需动态重算
- Flex 布局在深层嵌套时继承链不稳定,
calc()方案更可靠 - 行拖拽和列拖拽通过统一的
draggable属性配置,降低使用复杂度 - 拖拽结束后需要 emit 对应事件,让调用方感知数据顺序变化
- 建议先暂停视频自行尝试实现,再对照课程讲解验证思路
↑