心莫急,马上来咯🫵
1天前
在企业级中后台系统中,列表表格是使用频率最高的组件之一。随着项目的增长,复制粘贴的表格逻辑会导致大量重复代码和维护成本。为了解决这一问题,我们封装了一个通用的 TableLayout
组件,并配合分页钩子 useTablePagination
,统一管理分页、排序、查询等逻辑。
TableLayout
是一个功能完整的表格布局组件,集成了查询区域、操作区域、表格展示和分页功能。该组件基于 Element Plus 的 el-table
组件进行封装,并结合 useTablePagination
钩子实现了数据加载和分页的统一管理。
TableLayout
├── 查询区域 (可折叠)
├── 表格区域
│ ├── 操作工具栏
│ ├── 表格主体
│ └── 分页器
└── 右侧工具栏
useTablePagination
钩子统一管理表格数据属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
fetchApi | Function | () => | 数据获取函数 |
params | Object | 查询参数对象 | |
formatData | Function | data => data | 数据格式化函数 |
isPagination | Boolean | true | 是否显示分页 |
defaultSort | Object | null | 默认排序配置 |
...attrs | - | - | 可接受所有el-table 的参数或者方法 |
插槽名 | 说明 |
---|---|
query | 查询区域内容 |
operation | 操作区域内容 |
table | 表格列定义 |
提供表格数据加载、分页管理的统一解决方案。
typescriptfunction useTablePagination<T>(api: ApiParam<T>, options: TableOptions<T>): TablePaginationResult;
typescriptinterface TableOptions<T> { formatData?: (data: T[]) => any; immediate?: boolean; queryParams: ComputedRef<QueryParams> | QueryParams; }
typescript{ getTableData: () => Promise<void>; // 获取表格数据 pageRef: Ref<number>; // 当前页码 pageSizeRef: Ref<number>; // 每页条数 tableData: Ref<T[]>; // 表格数据 totalRef: Ref<number>; // 总条数 loadingRef: Ref<boolean>; // 加载状态 }
vue<template> <TableLayout :fetch-api="fetchList" :params="queryParams" :format-data="formatTableData"> <!-- 查询区域 --> <template #query> <el-form :model="queryParams"> <!-- 查询表单内容 --> </el-form> </template> <!-- 操作区域 --> <template #operation> <el-button type="primary">新增</el-button> </template> <!-- 表格内容 --> <template #table> <el-table-column prop="name" label="名称" /> <el-table-column prop="status" label="状态" /> </template> </TableLayout> </template> <script setup lang="ts"> import { ref } from 'vue'; const queryParams = ref({ pageNum: 1, pageSize: 10 // 其他查询参数 }); const fetchList = async (params) => { // 实现数据获取逻辑 return { rows: [], total: 0 }; }; const formatTableData = (data) => { // 数据格式化逻辑 return data; }; </script>
typescriptconst queryParams = ref({ pageNum: 1, pageSize: 10, keyword: '', status: null });
typescriptimport { request } from '@/utils/request'; export function getList(params: QueryParams) { return request({ url: '/api/list', method: 'get', params }); }
typescriptconst formatTableData = (data: any[]) => { return data.map((item) => ({ ...item, statusText: item.status === 1 ? '启用' : '禁用' })); };
vue<TableLayout :default-sort="{ prop: 'date', order: 'descending' }"> <template #table> <el-table-column prop="date" label="日期" sortable /> </template> </TableLayout>
fetchApi
返回的数据格式符合 PageApiResult
接口要求formatData
处理特殊的数据转换需求immediate
选项控制初始加载typescriptinterface PageApiResult<T> { rows: T[]; total: number; }
typescriptinterface QueryParams { pageNum: number; pageSize: number; orderByColumn?: string; isAsc?: string; [key: string]: any; }
typescriptinterface Sort { prop: string; order: 'ascending' | 'descending'; }
通过 TableLayout
和 useTablePagination
的组合,可以极大地提升列表页的开发效率与一致性。该方案适用于中后台系统的通用数据列表场景,推荐在团队项目中统一规范使用。
👉 项目源码地址 欢迎 Star 或提出建议。
如果你在实践中遇到问题,欢迎评论交流。