VxeTablePro 二次封装组件文档
一、实现目的
在企业级后台管理系统开发中,表格是最常用的组件之一,往往需要实现分页、搜索、排序、编辑、导出、全屏等通用功能。重复开发这些功能会导致效率低下且样式/逻辑不统一。基于此,VxeTablePro 组件的封装主要目标如下:
- 功能聚合:整合表格常用功能(分页、搜索、排序、编辑、导出、全屏等),减少重复开发
- 统一规范:统一表格样式、交互逻辑和接口设计,提升系统一致性
- 简化使用:通过配置化方式快速生成表格,降低开发门槛
- 可扩展性:支持自定义插槽、事件和配置,满足个性化需求
- 类型安全:基于 TypeScript 开发,提供完整类型定义,减少运行时错误
二、实现方式
1. 组件结构设计
采用主组件+子组件+hooks的分层架构,实现关注点分离:
bash
VxeTablePro/
├── index.vue # 主组件(整合所有功能)
├── components/ # 子组件
│ ├── Toolbar/index.vue # 工具栏(新增、导出、全屏等按钮)
│ ├── SearchForm/index.vue # 搜索表单
│ ├── Modal/index.vue # 提示弹窗
│ └── ElmentSlots/index.vue # 动态组件渲染
├── hooks/
│ └── useTable.ts # 表格核心逻辑(数据请求、分页、排序等)
├── types.ts # 类型定义
└── index.scss # 样式文件
2. 核心逻辑封装
(1)数据处理层(useTable.ts)
采用组合式 API 封装表格核心逻辑,实现数据与视图分离:
- 数据请求:统一处理接口调用、加载状态和错误捕获
- 分页管理:封装 pageNo、pageSize、total 等分页参数及切换逻辑
- 搜索与重置:处理查询参数的更新与重置
- 排序逻辑:支持后端排序,转换排序参数格式
typescript
// 核心逻辑示例(useTable.ts)
export const useTable = (api, initParam, isPageable = true) => {
const state = reactive({
tableData: [],
pageable: { pageNo: 1, pageSize: 10, total: 0 },
loading: false,
searchParam: {}
})
// 获取表格数据
const getTableList = async () => {
state.loading = true
try {
const params = { ...state.searchParam, ...state.pageable }
const data = await api(params)
state.tableData = data.list
state.pageable.total = data.total
} finally {
state.loading = false
}
}
// 分页切换
const handleSizeChange = (size) => {
state.pageable.pageSize = size
getTableList()
}
return { ...toRefs(state), getTableList, handleSizeChange }
}
(2)视图组件层(index.vue)
主组件负责整合所有功能模块,通过 props 接收配置,通过插槽提供扩展能力:
- 表格渲染:基于 vxe-table 实现核心表格展示
- 功能整合:集成搜索表单、工具栏、分页组件
- 事件分发:统一处理编辑、删除、排序等事件
vue
<!-- 核心结构示例(index.vue) -->
<template>
<div class="vxe-commn-container-pro">
<!-- 搜索表单 -->
<SearchForm
ref="searchForm"
:formOptions="formOptions"
@search="getTableList"
/>
<!-- 工具栏 -->
<Toolbar
:tableRef="tableRef"
:exportHandler="exportHandler"
/>
<!-- 表格主体 -->
<vxe-table
ref="tableRef"
:data="tableData"
:loading="loading"
@sort-change="sortChangeEvent"
>
<vxe-column
v-for="item in columns"
:key="item.field"
v-bind="item"
/>
<!-- 操作列 -->
<vxe-column title="操作">
<template #default="{ row }">
<slot name="actionBtnSlot" :row="row" />
</template>
</vxe-column>
</vxe-table>
<!-- 分页 -->
<VxePagination
v-model:page="pageable.pageNo"
v-model:limit="pageable.pageSize"
:total="pageable.total"
/>
</div>
</template>
(3)功能组件层
- Toolbar:封装新增、导出、全屏、列设置等操作按钮,通过 props 控制按钮权限
- SearchForm:基于 vxe-form 实现搜索表单,支持多种表单类型
- Modal:统一提示弹窗,处理确认/取消逻辑
3. 扩展性设计
- 插槽机制:支持自定义操作按钮(actionBtnSlot)、表头内容、搜索项等
- 配置化:通过 columns 配置表格列属性,通过 props 控制功能开关(如 showToolbar、pagination)
- 事件回调:暴露 editSuccess、deleteRow 等事件,允许自定义业务逻辑
三、产出价值
- 开发效率提升:平均减少 60% 以上的表格相关代码量,一个标准表格页面可在 10 分钟内完成开发
- 维护成本降低:核心逻辑集中维护,修改一处即可影响所有使用该组件的页面
- 用户体验统一:统一的交互方式(如排序、导出、编辑)降低用户学习成本
- 功能完整性:内置常用功能,无需重复开发,避免功能遗漏
- 类型安全保障:完整的 TypeScript 类型定义,减少 30% 以上的类型相关错误
四、使用方式
1. 基础用法
vue
<template>
<VxeTablePro
:columns="columns"
:requestApi="fetchTableData"
:formOptions="formOptions"
/>
</template>
<script setup lang="ts">
import VxeTablePro from './VxeTablePro'
import { fetchTableData } from '@/api/table'
// 表格列配置
const columns = [
{ field: 'name', title: '名称', sortable: true },
{ field: 'date', title: '日期', showType: 'time' },
{ field: 'status', title: '状态', enum: statusEnum }
]
// 搜索表单配置
const formOptions = {
fields: [
{ field: 'name', title: '名称', el: 'input' },
{ field: 'status', title: '状态', el: 'select', elProps: { options: statusEnum } }
]
}
</script>
2. 核心配置项
参数 | 类型 | 说明 |
---|---|---|
columns | ColumnProps[] | 表格列配置 |
requestApi | (params) => Promise | 数据请求接口 |
formOptions | object | 搜索表单配置 |
pagination | boolean | 是否显示分页 |
actionsPermi | { del: boolean; edit: boolean } | 操作按钮权限 |
showToolbar | boolean | 是否显示工具栏 |
exportApi | (params) => Promise | 导出接口 |
3. 自定义操作按钮
vue
<VxeTablePro
:columns="columns"
:requestApi="fetchTableData"
>
<template #actionBtnSlot="{ row }">
<el-button @click="handleView(row)">查看</el-button>
<el-button @click="handleEdit(row)">编辑</el-button>
</template>
</VxeTablePro>
4. 事件处理
vue
<VxeTablePro
:columns="columns"
:requestApi="fetchTableData"
@editSuccess="handleEditSuccess"
@deleteRow="handleDelete"
/>
<script setup>
const handleEditSuccess = (row) => {
console.log('编辑成功', row)
}
const handleDelete = async (row) => {
await deleteApi(row.id)
// 重新加载数据
tableRef.value.getTableList()
}
</script>
五、总结
VxeTablePro 组件通过合理的分层设计和功能封装,在保持灵活性的同时大幅提升了表格开发效率。其核心思想是抽取共性、暴露个性:将重复出现的分页、搜索、排序等逻辑封装为内置功能,同时通过配置和插槽支持个性化需求。
该组件适合中大型后台系统,能够有效解决表格功能散乱、维护困难的问题,为开发团队提供统一的表格解决方案。
六、资料
1、项目中真实使用场景

2、链接
这个代码仓库中的VxeTablePro文件夹就是这个组件的全部源码
gitee.com/li-haibo-19...