TablePlus 高级表格
在 Table 基础上集成筛选、排序、多选、行展开、分页、加载状态等功能的高级表格组件,采用卡片式圆角设计。
基础用法
传入 data 和 columns 即可渲染表格,默认带边框、斑马纹和悬停高亮。
姓名 | 年龄 | 城市 | 邮箱 |
|---|---|---|---|
| 张三 | 28 | 北京 | zhangsan@example.com |
| 李四 | 32 | 上海 | lisi@example.com |
| 王五 | 25 | 广州 | wangwu@example.com |
| 赵六 | 30 | 深圳 | zhaoliu@example.com |
| 孙七 | 27 | 杭州 | sunqi@example.com |
| 周八 | 35 | 成都 | zhouba@example.com |
vue
<my-table-plus :data="data" :columns="columns" />
const columns = [
{ key: 'name', title: '姓名', sortable: true },
{ key: 'age', title: '年龄', sortable: true },
{ key: 'city', title: '城市' },
]
const data = [
{ name: '张三', age: 28, city: '北京' },
{ name: '李四', age: 32, city: '上海' },
]可筛选
filterable 在工具栏显示搜索框,实时过滤所有列的数据。
vue
<my-table-plus :data="data" :columns="columns" filterable title="员工列表" />排序与多选
selection 开启多选,结合列的 sortable: true 实现排序。
商品名称 | 价格 | 销量 | 评分 | |
|---|---|---|---|---|
| 无线蓝牙耳机 | 299 | 1523 | 4.8 | |
| 机械键盘 | 459 | 892 | 4.6 | |
| USB-C 扩展坞 | 199 | 2341 | 4.5 | |
| 4K 显示器 | 2499 | 456 | 4.9 | |
| 无线鼠标 | 129 | 3120 | 4.3 | |
| 笔记本电脑支架 | 89 | 5678 | 4.2 |
提示:点击表头排序,勾选行进行批量操作
vue
<my-table-plus :data="data" :columns="columns" selection stripe hover />
const columns = [
{ key: 'name', title: '商品名称', sortable: true },
{ key: 'price', title: '价格', sortable: true },
{ key: 'sales', title: '销量', sortable: true },
]行展开
expandable 开启行展开,通过 #expand 插槽自定义展开内容。
订单号 | 客户 | 金额 | 日期 | |
|---|---|---|---|---|
| ORD-20260728-001 | 张三 | ¥1,299.00 | 2026-07-28 | |
| ORD-20260727-002 | 李四 | ¥2,499.00 | 2026-07-27 | |
| ORD-20260726-003 | 王五 | ¥588.00 | 2026-07-26 |
vue
<my-table-plus :data="data" :columns="columns" expandable>
<template #expand="{ row }">
<div v-for="item in row.items" :key="item.name">
{{ item.name }} × {{ item.qty }}
</div>
</template>
</my-table-plus>分页
pagination 配置分页参数:total、currentPage、pageSize。
vue
<my-table-plus :data="data" :columns="columns"
:pagination="{ total: 35, currentPage: 1, pageSize: 8 }" />加载状态
loading 为 true 时显示加载遮罩层。
姓名 | 年龄 | 城市 | 邮箱 |
|---|
加载状态:加载中...
vue
<my-table-plus :data="data" :columns="columns" :loading="loading" loading-text="数据加载中..." />自定义列
通过具名插槽自定义列内容,插槽名为列的 key。
vue
<my-table-plus :data="data" :columns="columns">
<template #name="{ row }">
<span>{{ row.name }}</span>
</template>
<template #status="{ value }">
<my-tag :type="value === 'active' ? 'success' : 'danger'">
{{ value === 'active' ? '在职' : '离职' }}
</my-tag>
</template>
<template #action>
<a href="#">编辑</a>
<a href="#">删除</a>
</template>
</my-table-plus>组件结构
根元素 .my-table-plus 包含可选的工具栏(标题、搜索框、操作区)和表格区域(内嵌 my-table 组件,通过插槽透传列、空内容、展开行等)。
CSS 类名
| 类名 | 说明 |
|---|---|
.my-table-plus | 根元素 |
.my-table-plus__toolbar | 工具栏 |
.my-table-plus__toolbar-left | 工具栏左侧区域 |
.my-table-plus__toolbar-right | 工具栏右侧区域 |
.my-table-plus__title | 表格标题 |
.my-table-plus__filter | 搜索过滤栏 |
.my-table-plus__filter-icon | 搜索图标 |
.my-table-plus__filter-input | 搜索输入框 |
.my-table-plus__filter-clear | 清除搜索按钮 |
.my-table-plus__table-area | 表格容器 |
.my-table-plus__table-area.has-toolbar | 有工具栏时启用 |
API
TablePlus Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| data | 表格数据 | Record<string, any>[] | [] |
| columns | 列配置 | TableColumn[] | [] |
| title | 表格标题,显示在工具栏左侧 | string | — |
| filterable | 显示搜索筛选框 | boolean | false |
| filterPlaceholder | 搜索框占位文字 | string | '请输入关键词' |
| border | 是否显示边框 | boolean | true |
| stripe | 斑马纹 | boolean | true |
| hover | 行悬停高亮 | boolean | true |
| size | 尺寸 | 'large' | 'default' | 'small' | 'default' |
| loading | 加载状态 | boolean | false |
| loadingText | 加载文字 | string | '加载中...' |
| emptyText | 空数据文字 | string | '暂无数据' |
| rowKey | 行唯一标识字段或函数 | string | ((row) => string) | — |
| selection | 开启多选 | boolean | false |
| selectionModel | 已选行数据 (v-model) | Record<string, any>[] | [] |
| selectable | 行是否可选 | (row, index) => boolean | — |
| expandable | 开启行展开 | boolean | false |
| expandedRows | 已展开行 key 数组 | (string | number)[] | [] |
| defaultExpandAll | 默认展开全部 | boolean | false |
| accordion | 手风琴模式(仅展开一行) | boolean | false |
| defaultSort | 默认排序 | { key, order } | — |
| pagination | 分页配置 | TablePaginationConfig | false | — |
| virtualScroll | 虚拟滚动 | boolean | false |
| rowHeight | 虚拟滚动行高 | number | 48 |
| bodyHeight | 表格体高度 | number | string | — |
TablePlus Events
| 事件 | 说明 | 回调 |
|---|---|---|
| sort-change | 排序变更 | (sort: SortState) |
| selection-change | 选中行变更 | (rows: Record<string, any>[]) |
| update:selectionModel | 选中行 v-model | (rows: Record<string, any>[]) |
| row-click | 行点击 | (row, index) |
| cell-click | 单元格点击 | (row, column) |
| expand-change | 展开变更 | (row, expanded) |
| update:expandedRows | 展开行 v-model | (keys) |
| page-change | 页码变更 | (page: number) |
| page-size-change | 每页条数变更 | (size: number) |
| column-resize | 列宽变更 | (column, width) |
TablePlus Slots
| 名称 | 说明 | 作用域 |
|---|---|---|
| toolbar | 自定义工具栏内容 | — |
| actions | 工具栏右侧操作区 | — |
[col.key] | 自定义列内容 | { row, value, index } |
| empty | 空数据内容 | — |
| expand | 展开行内容 | { row, expanded } |
TableColumn
ts
interface TableColumn {
key: string
title: string
width?: string | number
minWidth?: string | number
align?: 'left' | 'center' | 'right'
sortable?: boolean | 'custom'
fixed?: 'left' | 'right'
resizable?: boolean
}TablePaginationConfig
ts
interface TablePaginationConfig {
total: number
currentPage: number
pageSize: number
pageSizes?: number[]
layout?: string
}