Skip to content
数据展示有已知边界

NnTable 表格

排序、筛选、分页和固定列。

示例

API

Props

名称类型默认值说明
columnsTableColumn[][]列定义,结构见下文。
dataSourceRecord<string, unknown>[][]表格数据。
paginationboolean | TablePaginationfalse 关闭分页;true、未传或传对象时,只要总行数大于 0 就显示分页。默认每页 10 条。
loadingboolean | { spinning?: boolean }false显示加载遮罩。对象形式只读取 spinning
scroll{ x?: number | string | boolean; y?: number | string }{}横向最小宽度与纵向最大高度。x: true/max-content 使用 min-width: max-content
rowKeystring | ((record, index) => PropertyKey)'key'行键;字符串字段缺失时继续回退到 record.key 和索引。
rowClassNamestring | ((record, index) => unknown)''行 class。
customRow(record, index) => object返回对象会 v-bind<tr>,可包含原生属性和事件监听器。
sizestring'middle'small 使用紧凑样式,其他值为默认样式。
borderedbooleanfalse显示表格边框。

TableColumn

ts
interface TableColumn {
    key?: PropertyKey;
    dataIndex?: string | PropertyKey[]; // 字符串支持 a.b.c 路径
    title?: unknown | (() => unknown);
    width?: number | string;
    align?: string;
    ellipsis?: boolean;
    fixed?: true | 'left' | 'right';
    sorter?: boolean | ((left: Record<string, unknown>, right: Record<string, unknown>) => number);
    sortDirections?: Array<'ascend' | 'descend' | null>;
    filters?: Array<{ text: unknown; value: unknown }>;
    onFilter?: (value: unknown, record: Record<string, unknown>) => boolean;
    customRender?: (context: TableCellContext) => unknown | { children: unknown };
    children?: TableColumn[];
}

interface TableCellContext {
    text: unknown;
    value: unknown; // 与 text 相同
    record: Record<string, unknown>;
    index: number; // 当前 displayedRows 中的索引
    column: TableColumn;
}
  • titlecustomRender 可返回 Vue 可渲染内容;customRender 返回普通 { children } 时只渲染其 children
  • dataIndex 可以是键数组或点分隔字符串。没有 customRender/bodyCell 时,数组以 , 连接,对象使用 JSON.stringify
  • sorter 为函数时在当前 dataSource 上执行客户端排序。其他真值只改变排序状态并触发 change,适合由父组件处理。
  • filters 显示多选筛选菜单;只有同时提供 onFilter 才会执行客户端过滤。
  • fixed 使用 CSS sticky。多个固定列的偏移只会累加可转为数字的 width

TablePagination

ts
interface TablePagination {
    current?: number;
    pageSize?: number;
    total?: number;
    showSizeChanger?: boolean;
    pageSizeOptions?: Array<number | string>; // 默认 10、20、50、100
    showQuickJumper?: boolean; // 默认显示,显式 false 才隐藏
    position?: string[]; // 包含 bottomCenter 时居中
    showTotal?: (total: number, range: [number, number]) => unknown;
    onChange?: (current: number, pageSize: number) => void;
    onShowSizeChange?: (current: number, pageSize: number) => void;
}

当有限数字 total 大于当前处理后的行数时,组件视为远程分页,不再切片 dataSource。传入 currentpageSize 后属于受控值,父组件应在回调或 change 后更新配置。

Events

事件参数说明
change(pagination, filters, sorter, extra)分页、页大小、排序或筛选确认后触发。

事件对象结构:

ts
interface TableChangePagination {
    current: number;
    pageSize: number;
    total: number;
}

type TableChangeFilters = Record<string, unknown[]>; // 键为 column.key/dataIndex/生成键

interface TableChangeSorter {
    column?: TableColumn;
    columnKey?: string;
    field?: TableColumn['dataIndex'];
    order?: 'ascend' | 'descend' | null;
}

interface TableChangeExtra {
    currentDataSource: Record<string, unknown>[]; // 过滤、排序后的全部当前数据,不是当前页切片
}

没有有效排序时 sorter 是空对象。

Slots

名称作用域参数说明
bodyCell{ column, record, index, text, value }每个单元格都会调用。返回至少一个有意义节点时优先于 column.customRender 和原始值。
emptyText替换空表格中的默认 NnEmpty

当前限制

  • children 只展开一层为普通叶列,不渲染分组表头;更深层 children 不会继续展开。
  • 没有列级命名插槽、行选择、展开行、合并单元格或受控 sorter/filter 状态。
  • 默认分页是开启的;需要完整展示全部数据时必须显式传 :pagination="false"
  • 远程模式只避免分页切片;若仍传入函数 sorteronFilter,当前页数据仍会在客户端处理。

Released under the MIT License.