Table
基于 VXE-Table 封装的表格组件,支持分页、列配置、操作按钮、字典列、标签列等功能。
基础用法
vue
<template>
<PageTemplate>
<template #table>
<Table />
</template>
</PageTemplate>
</template>Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
otherHeight | number | 0 | 额外高度偏移,用于页面有其他固定高度元素时 |
instanceKey | string | symbol | - | 实例隔离标识符,优先使用 props,其次使用注入的值 |
Events
| 事件 | 参数 | 说明 |
|---|---|---|
checkbox | records | 复选框选中状态变化时触发 |
getData | - | 数据刷新时触发 |
vue
<template>
<PageTemplate>
<template #table>
<Table @checkbox="handleCheckbox" />
</template>
</PageTemplate>
</template>
<script setup>
const handleCheckbox = (records) => {
console.log("选中的数据", records);
};
</script>Exposed
通过 ref 获取组件实例后可访问 VXE-Table 的 grid 实例:
vue
<script setup>
import { ref } from "vue";
const tableRef = ref();
// 获取 VXE-Table grid 实例
const getGridInstance = () => {
return tableRef.value?.gridRef;
};
// 获取选中数据
const getSelectedRows = () => {
const grid = tableRef.value?.gridRef;
return grid?.getCheckboxRecords() || [];
};
// 清空选中
const clearSelection = () => {
const grid = tableRef.value?.gridRef;
grid?.clearCheckboxRow();
};
</script>
<template>
<PageTemplate>
<template #table>
<Table ref="tableRef" />
</template>
</PageTemplate>
</template>列配置
基础列配置
typescript
import { defineColumnsConfig } from "vue-admin-kit";
const columnsConfig = defineColumnsConfig([
// 复选框列
{ type: "checkbox", width: 50 },
// 序号列
{ type: "seq", title: "序号", width: 60 },
// 普通列
{ field: "name", title: "名称", minWidth: 120 },
// 固定列
{ field: "id", title: "ID", width: 80, fixed: "left" },
// 可排序列
{ field: "createTime", title: "创建时间", width: 160, sortable: true },
// 自定义格式化
{
field: "price",
title: "价格",
width: 100,
formatter: ({ cellValue }) => `¥${cellValue?.toFixed(2) || "0.00"}`,
},
]);列配置属性
| 属性 | 类型 | 说明 |
|---|---|---|
type | 'checkbox' | 'seq' | 列类型:复选框或序号 |
field | string | 字段名 |
title | string | 列标题 |
width | number | 列宽度(固定) |
minWidth | number | 最小宽度(自适应) |
fixed | 'left' | 'right' | 固定列位置 |
sortable | boolean | 是否可排序 |
align | 'left' | 'center' | 'right' | 对齐方式 |
showOverflow | boolean | 'tooltip' | 内容溢出处理,默认 'tooltip' |
formatter | (params) => string | 自定义格式化函数 |
dictType | string | 字典类型,自动转换显示 |
displayType | 'text' | 'tag' | 字典列显示类型 |
tags | TagConfig | 标签渲染配置 |
show | boolean | Function | 显示条件 |
字典列
自动将字段值转换为字典标签显示:
typescript
const columnsConfig = defineColumnsConfig([
// 文本显示
{
field: "status",
title: "状态",
dictType: "sys_status",
displayType: "text", // 默认
},
// 标签显示(带颜色)
{
field: "status",
title: "状态",
dictType: "sys_status",
displayType: "tag",
},
]);条件显示列
typescript
const columnsConfig = defineColumnsConfig([
// 布尔值
{ field: "remark", title: "备注", show: false },
// 函数判断
{
field: "adminRemark",
title: "管理员备注",
show: ({ pageData }) => pageData.params?.isAdmin === true,
},
]);标签列渲染 (tags)
在单元格内容后追加显示标签数组,适用于展示客户标签、风险标识等场景。
基础用法
typescript
const columnsConfig = defineColumnsConfig([
// 最简用法:从当前列的 field 读取标签数据
{
field: "tagList",
title: "标签",
tags: {},
},
// 从其他字段读取
{
field: "customerName",
title: "客户名称",
tags: {
field: "customerTags", // 标签数据来源字段
},
},
// 静态标签
{
field: "vipName",
title: "VIP客户",
tags: {
data: [
{ label: "VIP", type: "success" },
{ label: "重点客户", type: "warning", effect: "dark" },
],
},
},
]);标签样式映射
typescript
const columnsConfig = defineColumnsConfig([
// 按标签文本映射类型
{
field: "supplierName",
title: "供应商名称",
tags: {
field: "riskTags",
typeMap: {
利宝黑: "danger",
黑名单: "danger",
VIP: "success",
新客户: "info",
},
},
},
// 按标签文本映射完整属性
{
field: "orderNo",
title: "订单号",
tags: {
field: "statusTags",
propsMap: {
紧急: { type: "danger", effect: "dark" },
已完成: { type: "success", effect: "light" },
处理中: { type: "warning", effect: "plain" },
},
},
},
]);限制显示数量
typescript
{
field: "productName",
title: "产品名称",
tags: {
field: "labels",
max: 3, // 最多显示 3 个,超出显示 "+N"
size: "small",
effect: "plain",
},
}支持的数据格式
typescript
// 1. 字符串数组(最常用)
row.tagList = ["利宝黑", "VIP", "新客户"];
// 2. 对象数组(自带类型)
row.tagList = [
{ label: "利宝黑", type: "danger" },
{ label: "VIP", type: "success" },
];
// 3. 单字符串
row.tagList = "利宝黑";TagConfig 配置项
| 属性 | 类型 | 说明 |
|---|---|---|
data | TagData | 静态标签数据,直接渲染(优先级高于 field) |
field | string | 标签数据来源字段,默认使用当前列的 field |
typeMap | Record<string, TagType> | 按标签文本映射类型样式 |
propsMap | Record<string, Partial<TagProps>> | 按标签文本映射完整 Tag 属性 |
max | number | 最大显示数量,超出显示 "+N" |
type | TagType | 默认标签类型 |
size | 'large' | 'default' | 'small' | 标签尺寸 |
effect | 'dark' | 'light' | 'plain' | 标签主题 |
属性优先级
从低到高:内置默认值 → TagConfig 属性 → propsMap 映射 → typeMap 映射 → TagItem 自带属性
表格高度
自动计算
Table 组件会自动计算高度以适应页面,需要在 setupPageTemplate 中配置 calculateHeight:
typescript
setupPageTemplate({
dependencies: {
calculateHeight: (formHeight, otherHeight = 0) => {
return window.innerHeight - formHeight - otherHeight - 200;
},
},
});额外高度偏移
当页面有额外的固定高度元素时,通过 otherHeight 传入偏移:
vue
<template>
<!-- 页面有额外的 Tab 栏,高度 40px -->
<div class="tab-bar" style="height: 40px">...</div>
<PageTemplate>
<template #table>
<Table :otherHeight="40" />
</template>
</PageTemplate>
</template>多表格场景
使用 instanceKey 隔离各表格的高度状态:
vue
<template>
<PageTemplate :instance-key="Symbol('table1')">
<template #table>
<Table />
</template>
</PageTemplate>
</template>分页配置
分页通过 useState 的 paginationConfig 配置:
typescript
useState({
// ...
paginationConfig: {
pageSizes: [10, 20, 50, 100], // 每页条数选项
size: "default", // 分页组件尺寸
},
});透传属性
Table 组件支持透传 VXE-Table 的所有属性和事件:
vue
<template>
<PageTemplate>
<template #table>
<Table
:row-config="{ isHover: true }"
:sort-config="{ trigger: 'cell' }"
@cell-click="handleCellClick"
@sort-change="handleSortChange"
/>
</template>
</PageTemplate>
</template>
<script setup>
const handleCellClick = ({ row, column }) => {
console.log("点击单元格", row, column);
};
const handleSortChange = ({ field, order }) => {
console.log("排序变化", field, order);
};
</script>自定义插槽
Table 组件支持 VXE-Table 的所有插槽:
vue
<template>
<PageTemplate>
<template #table>
<Table>
<!-- 自定义单元格内容 -->
<template #name="{ row }">
<el-link type="primary" @click="handleClick(row)">
{{ row.name }}
</el-link>
</template>
<!-- 自定义表头 -->
<template #name_header>
<span
>名称 <el-icon><InfoFilled /></el-icon
></span>
</template>
</Table>
</template>
</PageTemplate>
</template>工具栏
Table 组件内置右侧工具栏,包含:
- 刷新按钮:重新获取数据
- 列设置:显示/隐藏列
工具栏按钮通过 tableOperationConfig 配置:
typescript
useState({
tableOptions: {
tableOperationConfig: [
{
title: "新增",
type: "primary",
icon: "Plus",
fixed: "left", // 显示在左侧
onClick: () => handleAdd(),
},
{
title: "导出",
type: "warning",
icon: "Download",
fixed: "right", // 显示在右侧
onClick: () => handleExport(),
},
],
},
});操作列
行操作按钮通过 operateColumns 配置:
typescript
import { defineOperateColumns, showWhen } from "vue-admin-kit";
useState({
tableOptions: {
operateColumns: defineOperateColumns([
{
title: "详情",
type: "info",
link: true,
onClick: (row) => handleDetail(row),
},
{
title: "编辑",
type: "primary",
link: true,
onClick: (row) => handleEdit(row),
hasPermi: ["system:user:edit"],
show: showWhen("status", "1"),
},
{
title: "删除",
type: "danger",
link: true,
onClick: (row) => handleDelete(row),
hasPermi: ["system:user:remove"],
},
]),
},
});操作列配置项
| 属性 | 类型 | 说明 |
|---|---|---|
title | string | 按钮文本 |
type | 'primary' | 'success' | 'warning' | 'danger' | 按钮类型 |
link | boolean | 是否为链接样式 |
icon | string | 图标名称 |
onClick | (row) => void | 点击回调 |
show | boolean | Function | 显示条件 |
hasPermi | string[] | 权限码 |
hasRole | string[] | 角色码 |
fixed | 'left' | 'right' | 固定位置(工具栏按钮) |
完整示例
vue
<script setup lang="ts">
import { ref } from "vue";
import {
useState,
PageTemplate,
Table,
defineColumnsConfig,
defineOperateColumns,
showWhen,
} from "vue-admin-kit";
const tableRef = ref();
const columnsConfig = defineColumnsConfig([
{ type: "checkbox", width: 50 },
{ type: "seq", title: "序号", width: 60 },
{ field: "name", title: "名称", minWidth: 150 },
{
field: "status",
title: "状态",
dictType: "sys_status",
displayType: "tag",
width: 100,
},
{
field: "customerName",
title: "客户",
minWidth: 200,
tags: {
field: "customerTags",
typeMap: { VIP: "success", 新客户: "info" },
max: 2,
},
},
{ field: "createTime", title: "创建时间", width: 160, sortable: true },
]);
useState({
api: { list: getList },
columnsConfig,
tableOptions: {
operateColumns: defineOperateColumns([
{ title: "编辑", onClick: (row) => handleEdit(row) },
{
title: "删除",
type: "danger",
onClick: (row) => handleDelete(row),
show: showWhen("status", "0"),
},
]),
},
});
</script>
<template>
<PageTemplate>
<template #table>
<Table
ref="tableRef"
:other-height="0"
:row-config="{ isHover: true }"
@checkbox="handleCheckbox"
/>
</template>
</PageTemplate>
</template>