Skip to content

表格、列与单元格 ​

已弃用(仅适用于 5.x)

本页只适用于 5.x 线(npm 5.1.x,分支 5.x)。@ahoo-wang/fetcher-viewer 已在 npm 上弃用(所有版本),并冻结在该线上:仅维护现有功能,不再新增功能。替代它的是 Wow 仓库的 @ahoo-wang/wow-view-engine(typescript/,wow.ahoo.me),自 Wow 9.2.0 起已发布到 npm(9.2.1 及以上兼容 fetcher 6)。两者模型与 API 不同,迁移需要适配。

ViewTable<RecordType> 将 FieldDefinition/ViewColumn 映射为 Ant Design 列,接收记录数组,不分页或查询服务端。必填 fields、columns、dataSource、enableRowSelection、viewTableSetting(false 或设置);attributes 可转发表格 props,tableSize 默认 middle。

渲染与选择 ​

列名使用点分路径。渲染优先级为 field.render、主键渲染器、已注册类型单元格、TextCell 回退。field.attributes 同时展开到列配置并能覆盖生成值,需要有意识地使用。主键/fixed 列固定 start,操作列固定 end。只有同时提供 actionColumn 和 viewTableSetting,才在操作列头显示设置浮层。TableSettingPanel 编辑 initialColumns 并发送 onChange,TableFieldItem 是条目控件,两者均不持久化配置。

useViewTableState 本地维护选择 key,clearSelectedRowKeys/reset 清空 key 数组,ViewTableRef 暴露这两个方法。onSelectChange 接收记录,onSortChanged 仅在排序操作时收到 Ant Design sorter 数组。dataSource 变化不自动清除选择。mapToTableRecord 优先主键、已有 key、行索引。attributes 在固定 scroll/size/onChange 前展开,最后这些配置仍由实现负责。

单元格契约 ​

所有 cell 接收 data: {value,record,index} 和可选类型专用 attributes。typedCellRender(type, attributes?) 返回 (value,record,index) => ReactNode,未知类型为 undefined。内置 text、primary-key、action/actions、tag/tags、datetime、calendar-time、image/image-group、link、currency、avatar;应使用公开 *_CELL_TYPE 常量,不猜键名。

DateTimeCell 默认 YYYY-MM-DD HH:mm:ss,无效/缺失日期显示 -。CalendarTimeCell 用 DEFAULT_CALENDAR_FORMATS 创建相对日历格式。formatCurrency 接受数值/字符串,用 Intl.NumberFormat,默认 CNY/symbol/2 位小数/zh-CN/分组 true/回退 -;解析后的非有限值使用回退,非法 Intl 参数仍可抛错。这是展示格式化,不是精确货币运算。ActionCell 将真值 data.value 显示为链接按钮,将当前记录传给 attributes.onClick,ActionsCell 组合主/次操作。AvatarCell 用 isValidImageSrc 选择图片或缩写/文本;ImageCell 只判断空值,ImageGroupCell 判断非空数组,均不验证网络可访问性。用户 render/actions 不由统一错误边界捕获。

单元格值 / attributes / 空值行为
TextCell值转字符串,null/undefined/空字符串显示 -,TextProps.children 覆盖展示。
PrimaryKeyCell值为链接文本,copyable 默认 true,attributes.onClick 接收 record。
TagCell / TagsCell空白标签不渲染;tags 使用字符串数组,attributes 按标签文本索引,可传 Space props。
LinkCell邮箱添加 mailto,其他值默认 target blank 和 rel noopener noreferrer;显式 href 优先,javascript/data/vbscript 协议替换为 #,显式 target/rel 归调用者负责。
ImageCell空值渲染 Empty,ImageProps 可覆盖 src 等图片选项。
ImageGroupCell空值/非数组渲染 Empty,首图为预览,多图增加数量徽标,alt 默认 Preview image。
AvatarCell空值为空 Avatar,合法 source 为图像,其他文本作为缩写,attributes 可覆盖 Avatar props。
CurrencyCellattributes.format 配置 formatCurrency,children 覆盖格式化文本。
CalendarTimeCell默认 sameDay/nextDay/lastDay 为今天/明天/昨天加 HH:mm,其余日期使用完整默认日期格式。

各 cell props、CurrencyFormatOptions、CalendarFormats 和准确常量见下文;Cells.stories.tsx 提供交互渲染示例。

完整示例 ​

tsx
import { ViewTable } from '@ahoo-wang/fetcher-viewer';
interface Item {
  id: string;
  price: number;
}
export function Prices() {
  return (
    <ViewTable<Item>
      fields={[
        { name: 'id', label: 'ID', type: 'text', primaryKey: true },
        { name: 'price', label: 'Price', type: 'currency', primaryKey: false },
      ]}
      columns={['id', 'price'].map(name => ({
        name,
        key: name,
        fixed: false,
        hidden: false,
      }))}
      dataSource={[{ id: '1', price: 12.5 }]}
      enableRowSelection={false}
      viewTableSetting={false}
      attributes={{ pagination: false }}
    />
  );
}

公开签名与类型 ​

以下签名按当前根入口可达声明核对。? 表示可省略;泛型/接口只约束编译期,继承项与关联类型可从 符号索引 定位。运行时默认值和失败行为以本页上文为准。

isActionCellProps ​

ts
export function isActionCellProps(obj: any): obj is ActionCellProps;

packages/viewer/src/table/cell/ActionCell.tsx:58

ActionCell ​

ts
export function ActionCell<RecordType = any>(
  props: ActionCellProps<RecordType>,
): import('react').JSX.Element | null;

packages/viewer/src/table/cell/ActionCell.tsx:122

ACTION_CELL_TYPE ​

ts
declare const ACTION_CELL_TYPE: string;

packages/viewer/src/table/cell/ActionCell.tsx:23

ActionCellProps ​

ts
export interface ActionCellProps<RecordType = any> extends CellProps<
  string,
  RecordType,
  Omit<ButtonProps, 'onClick'> & {
    onClick?: (record: RecordType) => void;
  }
> {}

packages/viewer/src/table/cell/ActionCell.tsx:50

ActionsCell ​

ts
export function ActionsCell<RecordType = any>(
  props: ActionsCellProps<RecordType>,
): React.JSX.Element;

packages/viewer/src/table/cell/ActionsCell.tsx:241

ACTIONS_CELL_TYPE ​

ts
declare const ACTIONS_CELL_TYPE: string;

packages/viewer/src/table/cell/ActionsCell.tsx:28

ActionsData ​

ts
export interface ActionsData<RecordType = any> {
  primaryAction:
    ActionCellProps<RecordType> | ((record: RecordType) => React.ReactNode);
  moreActionTitle?: string;
  secondaryActions:
    ActionCellProps<RecordType>[] | ((record: RecordType) => React.ReactNode[]);
}

packages/viewer/src/table/cell/ActionsCell.tsx:59

ActionsCellProps ​

ts
export interface ActionsCellProps<RecordType = any> extends CellProps<
  ActionsData<RecordType>,
  RecordType,
  {
    onClick: (actionKey: string, value: RecordType) => void;
  }
> {}

packages/viewer/src/table/cell/ActionsCell.tsx:97

AvatarCell ​

ts
export function AvatarCell<RecordType = any>(
  props: AvatarCellProps<RecordType>,
): import('react').JSX.Element;

packages/viewer/src/table/cell/AvatarCell.tsx:142

AVATAR_CELL_TYPE ​

ts
declare const AVATAR_CELL_TYPE: string;

packages/viewer/src/table/cell/AvatarCell.tsx:39

AvatarCellProps ​

ts
export interface AvatarCellProps<RecordType = any> extends CellProps<
  string,
  RecordType,
  AvatarProps
> {}

packages/viewer/src/table/cell/AvatarCell.tsx:69

CalendarTimeCell ​

ts
export function CalendarTimeCell<RecordType = any>(
  props: CalendarTimeProps<RecordType>,
): import('react').JSX.Element;

packages/viewer/src/table/cell/CalendarTime.tsx:208

CalendarFormats ​

ts
export interface CalendarFormats {
  sameDay?: string;
  nextDay?: string;
  nextWeek?: string;
  lastDay?: string;
  lastWeek?: string;
  sameElse?: string;
}

packages/viewer/src/table/cell/CalendarTime.tsx:40

CALENDAR_CELL_TYPE ​

ts
declare const CALENDAR_CELL_TYPE: 'calendar-time';

packages/viewer/src/table/cell/CalendarTime.tsx:78

DEFAULT_CALENDAR_FORMATS ​

ts
declare const DEFAULT_CALENDAR_FORMATS: CalendarFormats;

packages/viewer/src/table/cell/CalendarTime.tsx:89

CalendarTimeProps ​

ts
export interface CalendarTimeProps<RecordType = any> extends CellProps<
  string | number | Date | Dayjs,
  RecordType,
  TextProps & {
    formats?: CalendarFormats;
  }
> {}

packages/viewer/src/table/cell/CalendarTime.tsx:129

cellRegistry ​

ts
declare const cellRegistry: TypedComponentRegistry<
  string,
  CellProps<any, any, any>
>;

packages/viewer/src/table/cell/cellRegistry.ts:67

formatCurrency ​

ts
export function formatCurrency(
  amount: number | string | null,
  options?: CurrencyFormatOptions,
): string;

实现默认值: options = DEFAULT_CURRENCY_FORMAT_OPTIONS.

packages/viewer/src/table/cell/currencyFormatter.ts:200

CurrencyFormatOptions ​

ts
export interface CurrencyFormatOptions {
  currency?: string;
  currencyDisplay?: Intl.NumberFormatOptionsCurrencyDisplay;
  decimals?: number;
  locale?: string;
  useGrouping?: boolean;
  fallback?: string;
}

packages/viewer/src/table/cell/currencyFormatter.ts:35

DEFAULT_CURRENCY_FORMAT_OPTIONS ​

ts
declare const DEFAULT_CURRENCY_FORMAT_OPTIONS: CurrencyFormatOptions;

packages/viewer/src/table/cell/currencyFormatter.ts:117

CurrencyCell ​

ts
export function CurrencyCell<RecordType = any>(
  props: CurrencyCellProps<RecordType>,
): import('react').JSX.Element;

packages/viewer/src/table/cell/CurrencyCell.tsx:298

CURRENCY_CELL_TYPE ​

ts
declare const CURRENCY_CELL_TYPE: string;

packages/viewer/src/table/cell/CurrencyCell.tsx:58

CurrencyAttributes ​

ts
export interface CurrencyAttributes extends TextProps {
  format?: CurrencyFormatOptions;
}

packages/viewer/src/table/cell/CurrencyCell.tsx:102

CurrencyCellProps ​

ts
export interface CurrencyCellProps<RecordType = any> extends CellProps<
  number | string,
  RecordType,
  CurrencyAttributes
> {}

packages/viewer/src/table/cell/CurrencyCell.tsx:163

DateTimeCell ​

ts
export function DateTimeCell<RecordType = any>(
  props: DateTimeCellProps<RecordType>,
): import('react').JSX.Element;

packages/viewer/src/table/cell/DateTimeCell.tsx:146

DATETIME_CELL_TYPE ​

ts
declare const DATETIME_CELL_TYPE: string;

packages/viewer/src/table/cell/DateTimeCell.tsx:42

DateTimeCellProps ​

ts
export interface DateTimeCellProps<RecordType = any> extends CellProps<
  string | number | Date | Dayjs,
  RecordType,
  TextProps & {
    format?: string | ((dayjs: Dayjs) => string);
  }
> {}

packages/viewer/src/table/cell/DateTimeCell.tsx:72

DEFAULT_DATE_TIME_FORMAT ​

ts
declare const DEFAULT_DATE_TIME_FORMAT: 'YYYY-MM-DD HH:mm:ss';

packages/viewer/src/table/cell/DateTimeCell.tsx:78

ImageCell ​

ts
export function ImageCell<RecordType = any>(
  props: ImageCellProps<RecordType>,
): import('react').JSX.Element;

packages/viewer/src/table/cell/ImageCell.tsx:148

IMAGE_CELL_TYPE ​

ts
declare const IMAGE_CELL_TYPE: string;

packages/viewer/src/table/cell/ImageCell.tsx:39

ImageCellProps ​

ts
export interface ImageCellProps<RecordType = any> extends CellProps<
  string,
  RecordType,
  ImageProps
> {}

packages/viewer/src/table/cell/ImageCell.tsx:70

ImageGroupCell ​

ts
export function ImageGroupCell<RecordType = any>(
  props: ImageGroupCellProps<RecordType>,
): import('react').JSX.Element;

packages/viewer/src/table/cell/ImageGroupCell.tsx:149

IMAGE_GROUP_CELL_TYPE ​

ts
declare const IMAGE_GROUP_CELL_TYPE: string;

packages/viewer/src/table/cell/ImageGroupCell.tsx:40

ImageGroupCellProps ​

ts
export interface ImageGroupCellProps<RecordType = any> extends CellProps<
  string[],
  RecordType,
  PreviewGroupProps & Pick<ImageProps, 'alt'>
> {}

packages/viewer/src/table/cell/ImageGroupCell.tsx:71

LinkCell ​

ts
export function LinkCell<RecordType = any>(
  props: LinkCellProps<RecordType>,
): import('react').JSX.Element;

packages/viewer/src/table/cell/LinkCell.tsx:142

ts
declare const LINK_CELL_TYPE: string;

packages/viewer/src/table/cell/LinkCell.tsx:52

LinkCellProps ​

ts
export interface LinkCellProps<RecordType = any> extends CellProps<
  string,
  RecordType,
  LinkProps
> {}

packages/viewer/src/table/cell/LinkCell.tsx:79

PrimaryKeyCell ​

ts
export function PrimaryKeyCell<RecordType>(
  props: PrimaryKeyCellProps<RecordType>,
): import('react').JSX.Element;

packages/viewer/src/table/cell/PrimaryKeyCell.tsx:29

PRIMARY_KEY_CELL_TYPE ​

ts
declare const PRIMARY_KEY_CELL_TYPE: string;

packages/viewer/src/table/cell/PrimaryKeyCell.tsx:19

PrimaryKeyCellProps ​

ts
export interface PrimaryKeyCellProps<RecordType = any> extends CellProps<
  string,
  RecordType,
  Omit<LinkProps, 'onClick'> & {
    onClick?: (record: RecordType) => void;
  }
> {}

packages/viewer/src/table/cell/PrimaryKeyCell.tsx:21

TagCell ​

ts
export function TagCell<RecordType = any>(
  props: TagCellProps<RecordType>,
): import('react').JSX.Element | null;

packages/viewer/src/table/cell/TagCell.tsx:120

TAG_CELL_TYPE ​

ts
declare const TAG_CELL_TYPE: string;

packages/viewer/src/table/cell/TagCell.tsx:36

TagCellProps ​

ts
export interface TagCellProps<RecordType = any> extends CellProps<
  string,
  RecordType,
  TagProps
> {}

packages/viewer/src/table/cell/TagCell.tsx:63

TagsCell ​

ts
export function TagsCell<RecordType = any>(
  props: TagsCellProps<RecordType>,
): import('react').JSX.Element | null;

packages/viewer/src/table/cell/TagsCell.tsx:149

TAGS_CELL_TYPE ​

ts
declare const TAGS_CELL_TYPE: string;

packages/viewer/src/table/cell/TagsCell.tsx:41

TagsCellProps ​

ts
export interface TagsCellProps<RecordType = any> extends CellProps<
  string[],
  RecordType,
  Record<string, TagProps>
> {
  space?: SpaceProps;
}

packages/viewer/src/table/cell/TagsCell.tsx:72

TextCell ​

ts
export function TextCell<RecordType = any>(
  props: TextCellProps<RecordType>,
): import('react').JSX.Element;

packages/viewer/src/table/cell/TextCell.tsx:122

TEXT_CELL_TYPE ​

ts
declare const TEXT_CELL_TYPE: string;

packages/viewer/src/table/cell/TextCell.tsx:38

TextCellProps ​

ts
export interface TextCellProps<RecordType = any> extends CellProps<
  string,
  RecordType,
  TextProps
> {}

packages/viewer/src/table/cell/TextCell.tsx:64

typedCellRender ​

ts
export function typedCellRender<RecordType = any, Attributes = any>(
  type: CellType,
  attributes?: Attributes,
): CellRenderer<RecordType> | undefined;

packages/viewer/src/table/cell/TypedCell.tsx:117

CellType ​

ts
export type CellType = string;

packages/viewer/src/table/cell/TypedCell.tsx:31

CellRenderer ​

ts
export type CellRenderer<RecordType = any> = (
  value: any,
  record: RecordType,
  index: number,
) => React.ReactNode;

packages/viewer/src/table/cell/TypedCell.tsx:60

CellData ​

ts
export interface CellData<ValueType = any, RecordType = any> {
  value: ValueType;
  record: RecordType;
  index: number;
}

packages/viewer/src/table/cell/types.ts:47

CellProps ​

ts
export interface CellProps<
  ValueType = any,
  RecordType = any,
  Attributes = any,
> extends AttributesCapable<Attributes> {
  data: CellData<ValueType, RecordType>;
}

packages/viewer/src/table/cell/types.ts:100

CellComponent ​

ts
export type CellComponent<
  ValueType = any,
  RecordType = any,
  Attributes = any,
> = React.FC<CellProps<ValueType, RecordType, Attributes>>;

packages/viewer/src/table/cell/types.ts:147

parseDayjs ​

ts
export function parseDayjs(value: string | number | Date | Dayjs): Dayjs;

packages/viewer/src/table/cell/utils.ts:17

isNullOrUndefined ​

ts
export function isNullOrUndefined(value: any): value is null | undefined;

packages/viewer/src/table/cell/utils.ts:24

isValidImageSrc ​

ts
export function isValidImageSrc(value: any): value is string;

packages/viewer/src/table/cell/utils.ts:47

TableFieldItem ​

ts
export function TableFieldItem(
  props: TableFieldItemProps,
): import('react').JSX.Element;

packages/viewer/src/table/setting/TableFieldItem.tsx:69

TableFieldItemProps ​

ts
export interface TableFieldItemProps {
  columnDefinition: FieldDefinition;
  fixed: boolean;
  hidden: boolean;
  onVisibleChange: (hidden: boolean) => void;
}

packages/viewer/src/table/setting/TableFieldItem.tsx:47

TableSettingPanel ​

ts
export function TableSettingPanel(
  props: TableSettingPanelProps,
): React.JSX.Element;

packages/viewer/src/table/setting/TableSettingPanel.tsx:66

TableSettingPanelRef ​

ts
export interface TableSettingPanelRef {
  reset(): void;
}

packages/viewer/src/table/setting/TableSettingPanel.tsx:22

TableSettingPanelProps ​

ts
export interface TableSettingPanelProps extends RefAttributes<TableSettingPanelRef> {
  initialColumns: ViewColumn[];
  onChange?: (columns: ViewColumn[]) => void;
  fields: FieldDefinition[];
  className?: string;
}

packages/viewer/src/table/setting/TableSettingPanel.tsx:31

ColumnsCell ​

ts
export interface ColumnsCell {
  type: string;
  attributes?: any;
}

packages/viewer/src/table/types.ts:20

ViewTableActionColumn ​

ts
export interface ViewTableActionColumn<RecordType = any> {
  title: string;
  dataIndex?: string;
  actions: (record: RecordType) => ActionsData<RecordType>;
}

packages/viewer/src/table/types.ts:60

ViewTable ​

ts
export function ViewTable<RecordType>(
  props: ViewTableProps<RecordType>,
): import('react').JSX.Element;

packages/viewer/src/table/ViewTable.tsx:115

ViewTableRef ​

ts
export interface ViewTableRef {
  clearSelectedRowKeys: () => void;
  reset: () => void;
}

packages/viewer/src/table/ViewTable.tsx:44

ViewTableProps ​

ts
export interface ViewTableProps<RecordType = any>
  extends
    AttributesCapable<Omit<TableProps<RecordType>, 'columns' | 'dataSource'>>,
    PrimaryKeyClickHandlerCapable<RecordType>,
    ViewTableSettingCapable,
    TableSizeCapable,
    RefAttributes<ViewTableRef> {
  fields: FieldDefinition[];
  columns: ViewColumn[];
  onColumnsChange?: (columns: ViewColumn[]) => void;
  actionColumn?: ViewTableActionColumn<RecordType>;
  dataSource: RecordType[];
  enableRowSelection: boolean;
  onSortChanged?: (sorter: SorterResult<RecordType>[]) => void;
  onSelectChange?: (items: RecordType[]) => void;
  viewTableSetting: false | ViewTableSetting;
  loading?: boolean;
}

packages/viewer/src/table/ViewTable.tsx:57

useViewTableState ​

ts
export function useViewTableState(): ViewTableStateReturn;

packages/viewer/src/table/hooks/useViewTableState.ts:52

ViewTableStateReturn ​

ts
export interface ViewTableStateReturn {
  selectedRowKeys: Key[];
  setSelectedRowKeys: (keys: Key[]) => void;
  reset: () => void;
  clearSelectedRowKeys: () => void;
}

packages/viewer/src/table/hooks/useViewTableState.ts:21

相关专题 ​

模型与状态所有权 · View 与 Viewer 组合 · 已保存视图面板与持久化回调 · FetcherViewer 远端集成 · 过滤器与可编辑面板 · 注册表、输入与全屏按钮 · 工具栏、刷新与本地化

基于 Apache License 2.0 发布。