Skip to content

TablePro 表格组件

基于 TDesign Vue Next 的增强表格组件,提供搜索表单、分页、排序、过滤等高级功能。

功能特性

  • 🔍 智能搜索表单 - 自动根据列配置生成搜索表单
  • 📄 分页支持 - 内置分页功能,支持前端和后端分页
  • 🔄 数据请求 - 支持异步数据请求和自动加载状态
  • 📊 排序过滤 - 支持列排序和数据过滤
  • 🎨 插槽扩展 - 丰富的插槽支持,灵活定制表格头部和内容
  • 🔧 类型安全 - 完整的 TypeScript 类型定义
  • 📱 响应式布局 - 搜索表单自适应容器宽度

基础使用

Center Header
Left Header
Right Header
ID
Name
Age
Address
Email
Phone
Actions
1John Doe30123 Main St---
2Jane Smith25456 Elm St---
3Alice Johnson28789 Maple Ave---
4Bob Brown35101 Pine Rd---
5Charlie White22202 Oak St---
6Diana Green27303 Birch Blvd---
7Ethan Blue32404 Cedar Ct---
8Fiona Black29505 Spruce Dr---
9George Gray31606 Willow Way---
10Hannah Yellow26707 Cherry Ln---
11Ian Purple34808 Ash St---
12Julia Orange23909 Palm Pl---
13Kevin Pink301010 Magnolia Ave---
14Laura Cyan281111 Peach St---
15Mike Red331212 Maple St---
16Nina Teal241313 Cedar St---
17Oscar Silver361414 Oak St---
18Paula Gold211515 Pine St---
19Quinn Bronze291616 Birch St---
20Rita Copper321717 Spruce St---
共 0 条数据
50 条/页
  • 1
查看代码
vue
<template>
  <div class="base-table-container">
    <TablePro :columns="columns" row-key="id" :data="data">
      <template #tableHeaderCenter>
        <div>Center Header</div>
      </template>
      <template #tableHeaderLeft>
        <div>Left Header</div>
      </template>
      <template #tableHeaderRight>
        <div>Right Header</div>
      </template>
    </TablePro>
  </div>
</template>

<script setup lang="ts">
import type { ProTableCol } from 't-design-pro'
import { TablePro } from 't-design-pro'
import { useData } from 'vitepress'
import { ref, watch } from 'vue'

const { isDark } = useData()

watch(
  isDark,
  (newVal) => {
    document.documentElement.setAttribute('theme-mode', newVal ? 'dark' : 'light')
  },
  {
    immediate: true
  }
)

const columns = ref<ProTableCol[]>([
  {
    title: 'ID',
    colKey: 'id',
    width: 100,
    search: true,
    fixed: 'left'
  },
  {
    title: 'Name',
    colKey: 'name',
    width: 200,
    search: true
  },
  {
    title: 'Age',
    colKey: 'age',
    width: 100,
    search: true
  },
  {
    title: 'Address',
    colKey: 'address',
    width: 300,
    search: true
  },
  {
    title: 'Email',
    colKey: 'email',
    width: 200,
    search: true
  },
  {
    title: 'Phone',
    colKey: 'phone',
    width: 150,
    search: true
  },
  {
    title: 'Actions',
    colKey: 'operation',
    width: 150,
    fixed: 'right'
  }
])

const data = ref([
  { id: 1, name: 'John Doe', age: 30, address: '123 Main St' },
  { id: 2, name: 'Jane Smith', age: 25, address: '456 Elm St' },
  { id: 3, name: 'Alice Johnson', age: 28, address: '789 Maple Ave' },
  { id: 4, name: 'Bob Brown', age: 35, address: '101 Pine Rd' },
  { id: 5, name: 'Charlie White', age: 22, address: '202 Oak St' },
  { id: 6, name: 'Diana Green', age: 27, address: '303 Birch Blvd' },
  { id: 7, name: 'Ethan Blue', age: 32, address: '404 Cedar Ct' },
  { id: 8, name: 'Fiona Black', age: 29, address: '505 Spruce Dr' },
  { id: 9, name: 'George Gray', age: 31, address: '606 Willow Way' },
  { id: 10, name: 'Hannah Yellow', age: 26, address: '707 Cherry Ln' },
  { id: 11, name: 'Ian Purple', age: 34, address: '808 Ash St' },
  { id: 12, name: 'Julia Orange', age: 23, address: '909 Palm Pl' },
  { id: 13, name: 'Kevin Pink', age: 30, address: '1010 Magnolia Ave' },
  { id: 14, name: 'Laura Cyan', age: 28, address: '1111 Peach St' },
  { id: 15, name: 'Mike Red', age: 33, address: '1212 Maple St' },
  { id: 16, name: 'Nina Teal', age: 24, address: '1313 Cedar St' },
  { id: 17, name: 'Oscar Silver', age: 36, address: '1414 Oak St' },
  { id: 18, name: 'Paula Gold', age: 21, address: '1515 Pine St' },
  { id: 19, name: 'Quinn Bronze', age: 29, address: '1616 Birch St' },
  { id: 20, name: 'Rita Copper', age: 32, address: '1717 Spruce St' }
])
</script>

<style scoped>
.base-table-container {
  height: 700px;
}
</style>

动态请求数据

Name
Age
Address
暂无数据
共 0 条数据
50 条/页
  • 1
查看代码
vue
<template>
  <div>
    <TButton @click="refresh">刷新</TButton>
    <TablePro
      ref="tableRef"
      :columns="columns"
      row-key="id"
      :loading="loading"
      :request="request"
    ></TablePro>
  </div>
</template>

<script setup lang="ts">
import { TablePro } from 't-design-pro'
import { Button as TButton } from 'tdesign-vue-next'
import { useData } from 'vitepress'
import { ref, watch } from 'vue'

import type { ProTableCol } from '@/components/Table/types'

const { isDark } = useData()

watch(
  isDark,
  (newVal) => {
    document.documentElement.setAttribute('theme-mode', newVal ? 'dark' : 'light')
  },
  {
    immediate: true
  }
)

const columns = ref<ProTableCol[]>([
  {
    title: 'Name',
    colKey: 'name',
    width: 200
  },
  {
    title: 'Age',
    colKey: 'age',
    width: 100
  },
  {
    title: 'Address',
    colKey: 'address',
    width: 300
  }
])

const data = [
  { id: 1, name: 'John Doe', age: 30, address: '123 Main St' },
  { id: 2, name: 'Jane Smith', age: 25, address: '456 Elm St' },
  { id: 3, name: 'Alice Johnson', age: 28, address: '789 Maple Ave' },
  { id: 4, name: 'Bob Brown', age: 35, address: '101 Pine Rd' }
]

const getData = (params: { name: string }) => {
  console.log('params', params)

  return new Promise<{ data: any[]; total: number }>((resolve) => {
    setTimeout(() => {
      resolve({
        data,
        total: data.length
      })
    }, 1500)
  })
}

const loading = ref(false)
const request = async (params) => {
  try {
    loading.value = true
    const result = await getData(params)

    return {
      data: result.data,
      total: result.total
    }
  } catch {
    return null
  } finally {
    loading.value = false
  }
}

const tableRef = ref<InstanceType<typeof TablePro> | null>(null)

const refresh = () => {
  tableRef.value?.refresh()
}
</script>

<style></style>

API

Props

参数说明类型默认值
request数据请求方法ProTableRequestMethod-
extendParams请求扩展参数ExtendParams-
columns表格列配置ProTableCol[][]
data静态数据Array<any>-
rowKey行数据的唯一标识字段名string'id'
cellEmptyContent空单元格显示内容string'-'
pagination分页配置PaginationProps | null{ defaultCurrent: 1, defaultPageSize: 50 }
resetType表单重置类型'initial' | 'empty''initial'
tableProps透传给 EnhancedTable 的属性ProTablePropsOmitKey{}

ProTableCol 列配置

参数说明类型默认值
colKey列标识符string-
title列标题string | TNode-
width列宽度number | string-
fixed固定列位置'left' | 'right'-
hidden是否隐藏列booleanfalse
search搜索配置ProTableColSearchType | boolean-
cellContentEnum单元格内容枚举映射Record<string, any>-
cell自定义单元格渲染TNode-

ProTableColSearchType 搜索配置

参数说明类型默认值
key搜索字段名(默认使用 colKey)string-
label搜索表单标签string-
valueType搜索组件类型SearchValueType't-input'
valueEnum选择器选项枚举Record<string, any>-
fieldProps组件属性Record<string, any>-
render自定义渲染搜索组件() => VNode-

SearchValueType 搜索组件类型

支持的搜索组件类型:

  • 't-input' - 输入框
  • 't-select' - 选择器
  • 't-date-picker' - 日期选择器
  • 't-date-range-picker' - 日期范围选择器
  • VNode - 自定义组件

方法

方法名说明参数返回值
refresh刷新表格数据(不重置分页)--
reset重置表格(重置分页到第一页)--
restSearchForm重置搜索表单FormResetParams-
appendTo新增数据到指定位置(key: string, newData: any)-

插槽

插槽名说明参数
tableHeaderCenter表格头部中心区域-
tableHeaderLeft表格头部左侧区域-
tableHeaderRight表格头部右侧区域-
empty空数据状态-

事件

继承 TDesign EnhancedTable 的所有事件,主要包括:

  • change - 分页、排序、过滤变化时触发
  • select-change - 选择变化时触发
  • expand-change - 展开变化时触发

高级用法

搜索表单配置

vue
<template>
  <TablePro :columns="columns" :request="fetchData" />
</template>

<script setup>
const columns = [
  {
    title: '用户名',
    colKey: 'username',
    search: true // 简单搜索配置
  },
  {
    title: '状态',
    colKey: 'status',
    search: {
      valueType: 't-select',
      valueEnum: {
        active: '活跃',
        inactive: '非活跃'
      }
    }
  },
  {
    title: '创建时间',
    colKey: 'createTime',
    search: {
      valueType: 't-date-range-picker',
      fieldProps: {
        enableTimePicker: true
      }
    }
  }
]
</script>

自定义搜索组件

vue
<script setup>
const columns = [
  {
    title: '自定义搜索',
    colKey: 'custom',
    search: {
      render: () => h(CustomComponent, { 
        placeholder: '请输入关键词' 
      })
    }
  }
]
</script>

数据请求方法

javascript
const fetchData = async (params) => {
  const { current, pageSize, ...searchParams } = params
  
  const response = await api.getTableData({
    page: current,
    size: pageSize,
    ...searchParams
  })
  
  return {
    data: response.list,
    total: response.total
  }
}

表格头部插槽

vue
<template>
  <TablePro :columns="columns">
    <template #tableHeaderLeft>
      <t-button theme="primary">新增</t-button>
    </template>
    <template #tableHeaderRight>
      <t-button theme="default">导出</t-button>
      <t-button theme="default">设置</t-button>
    </template>
  </TablePro>
</template>

注意事项

  1. 数据请求方法request 方法需要返回 { data: Array, total: number } 格式的数据
  2. 列标识符:每列必须设置唯一的 colKey
  3. 搜索表单:只有设置了 search 属性的列才会出现在搜索表单中
  4. 分页处理:组件会自动处理分页参数传递和页码管理
  5. 响应式布局:搜索表单会根据容器宽度自动调整列数和布局