Skip to content

Table

基于 VXE-Table 封装的表格组件,支持分页、列配置、操作按钮、字典列、标签列等功能。

基础用法

vue
<template>
  <PageTemplate>
    <template #table>
      <Table />
    </template>
  </PageTemplate>
</template>

Props

属性类型默认值说明
otherHeightnumber0额外高度偏移,用于页面有其他固定高度元素时
instanceKeystring | symbol-实例隔离标识符,优先使用 props,其次使用注入的值

Events

事件参数说明
checkboxrecords复选框选中状态变化时触发
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'列类型:复选框或序号
fieldstring字段名
titlestring列标题
widthnumber列宽度(固定)
minWidthnumber最小宽度(自适应)
fixed'left' | 'right'固定列位置
sortableboolean是否可排序
align'left' | 'center' | 'right'对齐方式
showOverflowboolean | 'tooltip'内容溢出处理,默认 'tooltip'
formatter(params) => string自定义格式化函数
dictTypestring字典类型,自动转换显示
displayType'text' | 'tag'字典列显示类型
tagsTagConfig标签渲染配置
showboolean | 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 配置项

属性类型说明
dataTagData静态标签数据,直接渲染(优先级高于 field)
fieldstring标签数据来源字段,默认使用当前列的 field
typeMapRecord<string, TagType>按标签文本映射类型样式
propsMapRecord<string, Partial<TagProps>>按标签文本映射完整 Tag 属性
maxnumber最大显示数量,超出显示 "+N"
typeTagType默认标签类型
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>

分页配置

分页通过 useStatepaginationConfig 配置:

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"],
      },
    ]),
  },
});

操作列配置项

属性类型说明
titlestring按钮文本
type'primary' | 'success' | 'warning' | 'danger'按钮类型
linkboolean是否为链接样式
iconstring图标名称
onClick(row) => void点击回调
showboolean | Function显示条件
hasPermistring[]权限码
hasRolestring[]角色码
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>

Released under the MIT License.