Skip to content

AiTable 表格组件

基于 Naive UI DataTable 封装的增强型数据表格组件,支持表格/卡片双模式渲染、列设置、列宽拖拽、密度调整、分页、行展开、树形表等功能。通常由 AiCrudPage 内部调用,也可独立使用。

基础用法

vue
<template>
  <AiTable
    ref="tableRef"
    :columns="columns"
    :data-source="dataSource"
    :loading="loading"
    :pagination="pagination"
    @page-change="handlePageChange"
    @refresh="handleRefresh"
  />
</template>

<script setup>
import { ref } from 'vue'
import { AiTable } from '@/components/ai-form'

const tableRef = ref(null)

const columns = [
  { prop: 'name', label: '姓名', width: 120 },
  { prop: 'age', label: '年龄', width: 80, align: 'center' },
  { prop: 'status', label: '状态', width: 100, slot: 'status' },
  { prop: 'action', label: '操作', width: 180, fixed: 'right', slot: 'action' }
]

const dataSource = ref([])
const loading = ref(false)
const pagination = ref({ page: 1, pageSize: 10, itemCount: 0 })

function handlePageChange(page) {
  pagination.value.page = page
  fetchData()
}

function handleRefresh() {
  fetchData()
}
</script>

Props

基础属性

属性类型默认值说明
columnsArray<object>[]必填,表格列配置
dataSourceArray[]表格数据源
loadingBooleanfalse是否显示加载状态
paginationObject | Boolean{}分页配置,传 false 隐藏分页
rowKeyString | Function'id'行唯一标识字段名或函数

表格样式

属性类型默认值说明
stripedBooleanfalse是否显示斑马纹
borderedBooleantrue是否显示边框
sizeString'medium'表格尺寸:'small' | 'medium' | 'large'
rowGapNumber0行间距附加高度(px)
maxHeightNumber | String-表格最大高度,超出后纵向滚动
scrollXNumber-横向滚动最小宽度(px)
resizableBooleantrue列宽是否可拖拽调整

渲染模式

属性类型默认值说明
renderModeString'table'渲染模式:'table'(表格)| 'card'(卡片)
cardPropsObject{}卡片模式配置,如 { columns: 4, gap: 16, hoverable: true }
showRenderModeSwitchBooleanfalse是否显示列表/卡片切换按钮

选择与行操作

属性类型默认值说明
hideSelectionBooleanfalse是否隐藏多选框列
defaultSelectionArray[]默认选中行(键值数组)
expandConfigObject{}行展开面板配置(详见下方)
treeConfigObject{}树形表配置(详见下方)
tablePropsObject{}透传给 Naive UI DataTable 的额外属性

工具栏控制

属性类型默认值说明
showToolbarBooleantrue是否显示工具栏(刷新/密度/列设置)
showRefreshBooleantrue是否显示刷新按钮
showDensityBooleantrue是否显示密度调整下拉
showColumnFilterBooleantrue是否显示列设置按钮
showSearchToggleBooleanfalse是否显示搜索切换按钮
searchVisibleBooleanfalse搜索区域是否可见

列配置

每列配置对象支持以下属性:

属性类型说明
propString字段名(对应 dataSource 行数据中的 key)
labelString列标题
widthNumber | String列宽(px 或 CSS 值)
minWidthNumber最小宽度
fixedString固定列:'left''right'
alignString对齐方式:'left' | 'center' | 'right'
sortableBoolean是否可排序
sortOrderString默认排序方式:'ascend' | 'descend' | false
slotString自定义插槽名(仅在父组件中通过 <template #slotName> 渲染)
renderFunction自定义渲染函数:(row, index) => VNode | string
formatterFunction格式化函数:(value, row) => string
filterBoolean | Object是否启用列筛选及筛选配置
hideBoolean是否隐藏该列
ellipsisBoolean | Object文本溢出省略配置

列筛选:启用 filter: true 后,表头会出现筛选图标。也可传 { type: 'multiple', options: [...] } 自定义筛选器。

展开面板配置(expandConfig)

行展开面板支持多种渲染类型,配置如下:

js
const expandConfig = {
  type: 'table',         // 'table' | 'descriptions' | 'form' | 'tabs' | 'custom'
  title: '关联单据',     // 展开区域标题
  // 当 type='table' 时需配置:
  columns: [...],        // 子表格列配置
  api: 'get@/api/order/:id/items',  // 子数据接口(支持占位符)
  rowKey: 'itemId',      // 子表行键
  // 当 type='descriptions' 时需配置:
  schema: [...],         // 描述列表字段
  // 当 type='tabs' 时需配置:
  tabs: [                // 页签配置
    { key: 'detail', label: '详情', type: 'descriptions', schema: [...] },
    { key: 'history', label: '变更记录', type: 'table', columns: [...], api: '...' }
  ]
}

树形表配置(treeConfig)

js
const treeConfig = {
  key: 'id',             // 主键字段名
  parentKey: 'parentId', // 父节点字段名
  childrenKey: 'children', // 子节点字段名(后端返回树形结构时使用)
  defaultExpandAll: true  // 是否默认展开全部
}

事件

事件名参数说明
page-change(page: number)页码变化
page-size-change(pageSize: number)每页条数变化
refresh-点击刷新按钮
density-change(size: 'small' | 'medium' | 'large')密度变化
filter-change(visibleColumns: Array)列筛选变化(设置的可见列数组)
selection-change(keys: Array, rows: Array)选中行变化
row-click(row, index, event)行点击
expand-change(row, expanded)行展开/收起
render-mode-change(mode: 'table' | 'card')渲染模式切换
search-visible-change(visible: boolean)搜索区域显隐切换

方法

通过 ref 获取组件实例:

js
const tableRef = ref(null)

// 清除所有选中行
tableRef.value.clearSelection()

// 获取当前选中的行数据
const rows = tableRef.value.getCheckedRows()

// 获取当前选中的行键
const keys = tableRef.value.getCheckedKeys()

// 通过键值数组设置选中行
tableRef.value.setCheckedKeys([1, 2, 3])

// 刷新(重新触发 refresh 事件)
tableRef.value.refresh()

// 重置表格到初始状态(清除排序、筛选、选中)
tableRef.value.reset()

// 滚动到指定行(传入 rowKey 值)
tableRef.value.scrollTo(123)

插槽

vue
<AiTable :columns="columns" :data-source="dataSource">
  <!-- 列插槽 — slot 名对应 columns 中的 slot 属性 -->
  <template #status="{ row, index }">
    <n-tag :type="row.status === 1 ? 'success' : 'error'">
      {{ row.status === 1 ? '启用' : '禁用' }}
    </n-tag>
  </template>

  <!-- 操作列 -->
  <template #action="{ row }">
    <n-space>
      <n-button size="small" @click="handleEdit(row)">编辑</n-button>
      <n-button size="small" type="error" @click="handleDelete(row)">删除</n-button>
    </n-space>
  </template>

  <!-- 工具栏左侧 -->
  <template #toolbar-left>
    <n-button type="primary" @click="handleAdd">新增</n-button>
  </template>

  <!-- 工具栏右侧 -->
  <template #toolbar-right>
    <n-button @click="exportData">导出</n-button>
  </template>

  <!-- 卡片模式的自定义卡片渲染 -->
  <template #card="{ row, index }">
    <div class="custom-card">
      <h4>{{ row.title }}</h4>
      <p>{{ row.description }}</p>
    </div>
  </template>

  <!-- 展开行自定义内容(expandConfig.type='custom' 时生效) -->
  <template #expand="{ row }">
    <div class="expand-content">
      <p>自定义展开内容: {{ row.id }}</p>
    </div>
  </template>
</AiTable>

卡片模式

vue
<template>
  <AiTable
    :columns="productColumns"
    :data-source="products"
    :render-mode="'card'"
    :show-render-mode-switch="true"
    :card-props="{ columns: 3, gap: 16, hoverable: true }"
  >
    <template #card="{ row }">
      <n-card :title="row.name" hoverable>
        <template #cover>
          <img :src="row.image" style="height: 160px; object-fit: cover" />
        </template>
        <n-space vertical>
          <span class="price">¥{{ row.price }}</span>
          <n-tag>{{ row.category }}</n-tag>
        </n-space>
      </n-card>
    </template>
  </AiTable>
</template>

Forge Admin — 基于 Vue3 + Spring Boot 的企业级后台管理框架