交叉树状表格
交叉树状表格(CrossTreeTable)与交叉表(CrossTable)类似,但在表格左侧提供了树状展开/收拢的能力,更适用于日常业务开发。
#
主要特性- 不依赖特定组件库,可独立使用
- 简单、一致的 API 与渲染模型:
左树 + 上树 => 表格
- 高性能:数据量较大时,自动开启虚拟滚动
#
用法CrossTreeTable 主要由以下几个部分组成:
primaryColumn
描述表格第一列- 通过
leftTree
描述表格左侧的树状结构; - 通过
topTree
描述表格上方的树状结构; - 通过
getValue
来定义每个单元格内容; - CrossTreeTable 会根据 leftTree/topTree 来渲染表格结构,并调用
getValue
获取单元格的内容
// prettier-ignore<CrossTreeTable // 推荐为 CrossTreeTable 设置一个默认列宽 defaultColumnWidth={100}
// 非受控用法 defaultOpenKeys={[leftTree[0].key]}
// 受控用法 // openKeys={openKeys} // onChangeOpenKeys={nextOpenKeys => { /* update openKeys */ }}
// 表格第一列的配置 primaryColumn={{ lock: true, name: '数据维度', width: 200 }}
leftTree={leftTree} topTree={topTree} getValue={(leftNode, topNode) => { // 自定义的取数逻辑,针对每个单元格都会调用一次 // leftNode 表示当前单元格对应的左侧树节点,topNode 是对应的上方树节点 }}
// 可选的自定义的渲染逻辑 render={(value, leftNode, topNode) => { return value }}/>
预览点击展开或收拢
2021年 学习计划
源码点击展开或收拢
#
leftTree 的结构 / topTree 的结构leftTree/topTree 都是一个具有 key/value/children 嵌套结构的数组,详见 交叉表文档.
注意 CrossTreeTable 对于 leftTree 和 topTree 的处理有所不同:
- leftTree 中的每个节点对应表格中的一行,包括叶子节点和非叶节点
- topTree 中的叶子节点对应 表格上的一列
#
其他 propsCrossTreeTable 的底层依赖了 BaseTable
,故两者的 props 大部分是相同的。两者的不同点具体如下:
- CrossTreeTable 没有 dataSource 和 columns
- 表格结构由 leftTree 和 rightTree 提供,而单元格内容由 getValue 提供
- 单元格渲染内容可使用 render 进行自定义;单元格的 props(即表格内的 td 元素)可使用 getCellProps 进行自定义
- CrossTreeTable 没有 primaryKey
- CrossTreeTable 左侧树中每个节点都有一个唯一的 key 值,故不再需要上层指定 primaryKey
- 其他新增的 props
- CrossTreeTable 使用 primaryColumn 来描述 表格第一列的配置
- openKeys/onChangeOpenKeys/defaultOpenKeys:树状模式下展开节点的 key 数组
CrossTreeTable props 具体如下:
export interface CrossTreeTableProps extends Omit<BaseTableProps, 'dataSource' | 'columns' | 'primaryKey'> { primaryColumn: CrossTableLeftMetaColumn leftTree: LeftCrossTreeNode[] topTree: TopCrossTreeNode[]
defaultOpenKeys?: string[] openKeys?: string[] onChangeOpenKeys?(nextOpenKeys: string[]): void
getValue(leftNode: LeftCrossTreeNode, topNode: TopCrossTreeNode, leftDepth: number, topDepth: number): any render?( value: any, leftNode: LeftCrossTreeNode topNode: TopCrossTreeNode, leftDepth: number, topDepth: number, ): ReactNode getCellProps?( value: any, leftNode: LeftCrossTreeNode, topNode: TopCrossTreeNode, leftDepth: number, topDepth: number, ): CellProps}
export interface CrossTableLeftMetaColumn extends Omit<ArtColumnStaticPart, 'hidden'> { /** 自定义渲染方法 */ render?(leftNode: LeftCrossTreeNode, leftDepth: number): ReactNode
/** 自定义的获取单元格 props 的方法 */ getCellProps?(leftNode: LeftCrossTreeNode, leftDepth: number): CellProps}
不要被长长的 TypeScript 类型代码吓到,CrossTreeTable 的 props 其实和 BaseTable 差别不大。
#
交叉树状表格定制CrossTreeTable 的底层仍是 <BaseTable />
。
对 CrossTreeTable 进行定制时,可以先通过 buildCrossTreeTable
根据 CrossTreeTable 的输入生成 dataSource / columns,进行一些自定义的处理,然后再将处理好的数据传给 BaseTable,并注意为 BaseTable 设置 primaryKey={ROW_KEY}
。
可以使用 pipeline 进行表格功能拓展(具体可以参考这个示例),但因为 CrossTreeTable 本身很复杂,只有一部分比较简单的 pipeline feature 可以和 CrossTreeTable 一起工作.
import { BaseTable } from 'ali-react-table'import { buildCrossTreeTable, ROW_KEY } from 'ali-react-table/pivot'
function MyComplexTable() { // 将「传给 CrossTreeTable 的参数」传给 buildCrossTreeTable const { dataSource, columns } = buildCrossTreeTable({ leftTree, topTree, getValue, render,
// 调用 buildCrossTreeTable 必须传入一份受控的 openKeys 状态 openKeys: ['a', 'b', 'c'], onChangeOpenKeys(nextOpenKeys) {},
// 这里也支持 CrossTreeTable 的其他 props })
// 在这里可以对 dataSource 和 columns 进行一定的处理后,再将数据传递给 BaseTable
return ( <BaseTable className="my-complex-table" primaryKey={ROW_KEY} defaultColumnWidth={100} dataSource={dataSource} columns={columns} /> )}