import React from 'react'; interface TableColumn { title: React.ReactNode; dataIndex?: keyof T; key?: string; width?: number | string; render?: (value: any, record: T, index: number) => React.ReactNode; align?: 'left' | 'center' | 'right'; className?: string; } interface TableProps { columns: TableColumn[]; dataSource: T[]; rowKey: keyof T | ((record: T) => string); loading?: boolean; bordered?: boolean; emptyText?: React.ReactNode; className?: string; onRow?: (record: T, index: number) => React.HTMLAttributes; scroll?: { x?: number | string; y?: number | string; }; } export function Table>({ columns, dataSource, rowKey, loading = false, bordered = false, emptyText = '暂无数据', className = '', onRow, scroll, }: TableProps) { // 防御性检查:确保 dataSource 始终是数组 const safeDataSource = dataSource || []; const getRowKey = (record: T, index: number): string => { if (typeof rowKey === 'function') { return rowKey(record); } return String(record[rowKey]); }; // 是否启用固定表头滚动 const hasScrollY = scroll?.y !== undefined; // 渲染表头 const renderHeader = () => ( {columns.map((column, index) => ( {column.title} ))} ); // 渲染表体 const renderBody = () => ( {safeDataSource.length > 0 ? ( safeDataSource.map((record, index) => ( {columns.map((column, colIndex) => ( {column.render ? column.render( column.dataIndex ? record[column.dataIndex] : undefined, record, index ) : column.dataIndex ? record[column.dataIndex] : undefined} ))} )) ) : ( {emptyText} )} ); // 如果有垂直滚动,使用固定表头布局 if (hasScrollY) { return (
{/* 固定表头 */}
{columns.map((column, index) => ( ))} {renderHeader()}
{/* 可滚动表体 */}
{columns.map((column, index) => ( ))} {renderBody()}
{loading && (
加载中...
)}
); } // 默认布局(无滚动) return (
{renderHeader()} {renderBody()}
{loading && (
加载中...
)}
); }