Skip to content

ProTable 高级表格

概述

ProTable 是一个配置化驱动的高级表格组件,在 Ant Design Vue Table 基础上封装了搜索表单、工具栏、分页、列类型渲染等功能,大幅减少样板代码。

基本用法

vue
<script setup lang="ts">
import ProTable from '@/components/Pro/ProTable/index.vue'
import type { ProTableColumn, ProTableRequest } from '@/types/pro'

const columns: ProTableColumn[] = [
  {
    title: '姓名',
    dataIndex: 'name',
    search: true,
  },
  {
    title: '状态',
    dataIndex: 'status',
    valueType: 'tag',
    search: true,
    options: [
      { label: '启用', value: 'active', color: 'green' },
      { label: '禁用', value: 'inactive', color: 'red' },
    ],
  },
  {
    title: '创建时间',
    dataIndex: 'createdAt',
    valueType: 'dateTime',
  },
  {
    title: '操作',
    dataIndex: 'actions',
    actions: [
      { label: '编辑', onClick: (record) => handleEdit(record) },
      { label: '删除', danger: true, confirm: '确认删除?', onClick: (record) => handleDelete(record) },
    ],
  },
]

const request: ProTableRequest = async (params) => {
  const res = await fetchUsers(params)
  return { data: res.list, total: res.total, success: true }
}
</script>

<template>
  <ProTable :columns="columns" :request="request" />
</template>

Props

属性类型默认值说明
columnsProTableColumn[]必填列配置
requestProTableRequest必填数据请求函数
toolbarProTableToolbar工具栏配置
searchProTableSearch | false搜索表单配置,false 隐藏
headerFilterProTableHeaderFilterConfig表头筛选全局配置
paginationProTablePagination | false默认分页分页配置,false 隐藏
rowKeystring | ((record) => string)'id'行唯一标识
size'large' | 'middle' | 'small''small'表格密度
heightnumber | string | 'auto''auto'表格高度
resizablebooleantrue行是否可调整
columnResizablebooleantrue列宽是否可拖拽调整
ellipsisbooleantrue文本溢出省略
borderedbooleantrue是否显示边框
fixedHeaderbooleantrue是否固定表头
formItemsProFormItem[]内置 CRUD 弹窗的表单配置
formLayoutProFormLayout弹窗表单布局
formGridProFormGrid弹窗表单网格
formModalWidthnumber | string640弹窗宽度
formCreateTitlestring'新增'新建弹窗标题
formEditTitlestring'编辑'编辑弹窗标题

ProTableColumn

列配置接口,定义每一列的渲染、搜索和交互行为:

属性类型说明
titlestring列标题
dataIndexstring数据字段名
keystring可选唯一标识
widthnumber | string列宽
minWidthnumber | string最小列宽
fixed'left' | 'right'固定列位置
align'left' | 'center' | 'right'文本对齐
ellipsisboolean文本溢出省略
resizableboolean该列是否可拖拽调整宽度
hideInTableboolean是否在表格中隐藏
valueTypeValueType渲染类型
valueEnumRecord<string, { text, status?, color? }>枚举映射
valueTypePropsRecord<string, any>ValueType 渲染参数(如日期格式、货币符号等)
copyableboolean是否可复制
searchboolean是否生成搜索字段
searchTypeSearchType搜索字段类型(可选,自动从 valueType 推断:tag/badge→select,date/dateTime/time→datePicker,dateRange→dateRange,money/percent/progress→number,其他→input)
searchOptionsArray<{ label, value }>搜索下拉选项
searchPropsRecord<string, any>搜索字段额外属性
optionsArray<{ label, value, color?, status?, disabled? }>统一选项配置,自动派生 searchOptionsvalueEnum
headerFilterProTableHeaderFilter表头筛选配置
sorterboolean | ((a, b) => number)排序
defaultSortOrder'ascend' | 'descend'默认排序方向
actionsProTableAction[]操作列按钮
render(text, record, index) => any自定义渲染函数

ValueType 渲染类型

类型说明示例
text纯文本(默认)Hello
date日期2024-01-15,可通过 valueTypeProps.format 自定义
dateTime日期时间2024-01-15 14:30:00,可通过 valueTypeProps.format 自定义
dateRange日期范围
time时间14:30:00
tag标签(配合 valueEnum 使用)启用
badge徽章(配合 valueEnum 使用)
money金额(带 ¥ 和千分位)¥12,345.00,可通过 valueTypeProps.symbolvalueTypeProps.precision 自定义
percent百分比85.50%,可通过 valueTypeProps.precision 自定义精度
avatar头像(32px 圆形)可通过 valueTypeProps.size 自定义大小
image图片(80px 宽)可通过 valueTypeProps.width 自定义宽度
link链接
progress进度条

SearchType 搜索类型

类型说明
input文本输入框
select下拉选择(需配合 searchOptionsvalueEnum
dateRange日期范围选择器
datePicker日期选择器
number数字输入框
checkbox复选框
radio单选框

统一选项 (Unified Options)

通过 options 属性可以一次性定义列的选项数据,自动派生 valueEnum(用于渲染)和 searchOptions(用于搜索下拉):

typescript
{
  title: '状态',
  dataIndex: 'status',
  valueType: 'tag',
  search: true,
  options: [
    { label: '启用', value: 'active', color: 'green' },
    { label: '禁用', value: 'inactive', color: 'red' },
  ],
}

等价于分别设置 valueEnum + searchOptions,减少重复配置。如果同时设置了 optionsvalueEnum/searchOptions,后者优先。

valueTypeProps 格式化参数

通过 valueTypeProps 自定义 ValueType 的渲染参数:

typescript
const columns: ProTableColumn[] = [
  {
    title: '创建时间',
    dataIndex: 'createdAt',
    valueType: 'date',
    valueTypeProps: { format: 'YYYY/MM/DD' },
  },
  {
    title: '金额',
    dataIndex: 'amount',
    valueType: 'money',
    valueTypeProps: { symbol: '$', precision: 0 },
  },
  {
    title: '完成度',
    dataIndex: 'progress',
    valueType: 'progress',
    valueTypeProps: { strokeColor: '#52c41a', showInfo: true },
  },
]
ValueType可用参数说明
dateformat日期格式,默认 'YYYY-MM-DD'
dateTimeformat日期时间格式,默认 'YYYY-MM-DD HH:mm:ss'
moneysymbol, precision货币符号(默认 ¥)和小数位数(默认 2
percentprecision小数位数(默认 2
avatarsize头像大小(默认 32
imagewidth图片宽度(默认 80
progress所有 a-progress 属性直接透传给进度条组件

ProTableAction 操作列

操作列用于定义行级操作按钮:

属性类型说明
labelstring按钮文本
type'link' | 'button' | 'dropdown'按钮类型
iconany按钮图标
permissionstring所需权限码
dangerboolean是否为危险操作
disabled(record) => boolean是否禁用
hidden(record) => boolean是否隐藏
confirmstring确认提示文本(显示确认弹窗)
onClick(record) => void | Promise<void>点击回调
itemsProTableAction[]下拉菜单子项(type 为 dropdown 时)
typescript
actions: [
  {
    label: '编辑',
    permission: 'user.edit',
    onClick: (record) => openEditModal(record),
  },
  {
    label: '更多',
    type: 'dropdown',
    items: [
      { label: '重置密码', onClick: (record) => resetPassword(record) },
      { label: '删除', danger: true, confirm: '确认删除?', onClick: (record) => deleteUser(record) },
    ],
  },
]

ProTableHeaderFilter 表头筛选

支持列级表头筛选,提供关键字搜索和下拉选择两种类型:

属性类型说明
type'keyword' | 'select'筛选类型
mode'client' | 'server' | 'hybrid'筛选模式
icon'search' | 'filter'图标类型
paramKeystring服务端参数名
placeholderstring占位文本
multipleboolean是否多选(select 类型)
optionsArray<{ label, value }>下拉选项(select 类型)

筛选模式说明:

  • client — 前端过滤,不发请求
  • server — 服务端过滤,筛选参数随请求发送
  • hybrid — 先发请求获取数据,再进行前端过滤

Toolbar 工具栏

typescript
const toolbar: ProTableToolbar = {
  title: '用户列表',
  subTitle: '管理系统用户',
  // 隐藏默认工具按钮前加 !
  actions: ['!density'],  // 隐藏密度切换
}

内置工具:

  • 刷新 — 重新加载数据
  • 密度 — 切换表格密度(large/middle/small)
  • 列设置 — 列显示/隐藏、排序、固定

Events

事件参数说明
refresh刷新按钮点击时触发
form-submit{ values, record, isEdit }内置表单提交时触发

Slots

插槽名说明
toolbar-actions工具栏右侧自定义操作区域
bodyCell自定义单元格渲染

内置 CRUD 弹窗

通过 formItems 配置,ProTable 可内置 CRUD 弹窗,无需手动管理 ProModal + ProForm:

vue
<script setup lang="ts">
import ProTable from '@/components/Pro/ProTable/index.vue'
import type { ProTableColumn, ProFormItem } from '@/types/pro'

const tableRef = ref()

const columns: ProTableColumn[] = [
  { title: '姓名', dataIndex: 'name', search: true },
  { title: '邮箱', dataIndex: 'email' },
  {
    title: '操作',
    dataIndex: 'action',
    actions: [
      { label: '编辑', onClick: (record) => tableRef.value?.openEditModal(record) },
    ],
  },
]

const formItems: ProFormItem[] = [
  { name: 'name', label: '姓名', type: 'input', required: true },
  { name: 'email', label: '邮箱', type: 'input' },
]

const handleFormSubmit = async ({ values, record, isEdit }) => {
  if (isEdit) {
    await updateUser(record.id, values)
  } else {
    await createUser(values)
  }
  tableRef.value?.refresh()
}
</script>

<template>
  <ProTable
    ref="tableRef"
    :columns="columns"
    :request="request"
    :form-items="formItems"
    :form-grid="{ cols: 2 }"
    @form-submit="handleFormSubmit"
  >
    <template #toolbar-actions>
      <a-button type="primary" @click="tableRef?.openCreateModal()">新增</a-button>
    </template>
  </ProTable>
</template>

暴露方法

方法说明
refresh()使用当前参数重新加载数据
reload()重置分页到第一页并重新加载
openCreateModal(initialValues?)打开新建弹窗
openEditModal(record)打开编辑弹窗(自动填充数据)
vue
<script setup lang="ts">
const tableRef = ref()

// 刷新数据
tableRef.value?.refresh()

// 重置并刷新
tableRef.value?.reload()
</script>

<template>
  <ProTable ref="tableRef" :columns="columns" :request="request" />
</template>

ProTableRequest

数据请求函数的类型定义:

typescript
interface ProTableRequest {
  (params: Record<string, any>): Promise<{
    data: any[]      // 数据列表
    total?: number   // 总条数(用于分页)
    success: boolean // 请求是否成功
  }>
}

params 参数包含分页信息和搜索表单的值:

typescript
{
  current: 1,       // 当前页码
  pageSize: 10,     // 每页条数
  name: '张三',     // 搜索字段值
  status: 'active', // 搜索字段值
}

基于 MIT 许可发布