如何封装一个Table组件

如何封装一个Table组件

Tags
js
前端
description
封装一个好用的Table组件
更新时间
Last updated January 28, 2022

概览

 
从业务逻辑上来说,一个Table组件提供了通用列表的功能,尤其是针对大量的结构化数据的展示,通常我们还需要提供行选择,多行选择,排序,搜索,分页,自定义操作等功能,Table的每一行的宽度是需要自定义的,有可能需要固定表头,固定列,甚至表头分组等功能
 

功能及实现逻辑

我们基础的UI框架采用了Material-UI,所以基础DOM都是基于MaterialUI进行组织
 

表头及列展示

 
表头的数据我们可以作为一个单独的参数fields传入,用于标志这一列,同时我们传入data,利用fields来对data进行数据的筛选和关键值的渲染
export interface PTableField<DataType> { title: string; key: string; align?: 'left' | 'right' | 'center'; render?: (text: any, row: DataType, index: number) => JSX.Element; };
字段
描述
表头的标题
当前列所要取key,同时也是React需要的key
文字的对齐方向
自定义渲染
每一行的数据放在data字段中,根据表头数据fields的字段去获取data中的数据然后进行渲染,根据render是否存在来判断是直接渲染成文字还是自定义渲染
const fields: PTableField<NodeSpec>[] = [{ title: intl.get('节点名称').defaultMessage('节点名称'), key: 'name', render: function renderItem(text, row) { return ( <Link href={`/dashboard/nodes/${row.id}`}>{text}</Link> ); } }, { title: intl.get('IP地址').defaultMessage('IP地址'), key: 'adminIp', align: 'right' }, { title: intl.get('创建时间').defaultMessage('创建时间'), key: 'createdAt', align: 'right' }, { title: intl.get('更新时间').defaultMessage('更新时间'), key: 'updatedAt', align: 'right' }]; const tdata: NodeSpec[] = data?.map(item => Object.assign({}, item.spec, { createdAt: moment(item.spec.createdAt).format('YYYY-MM-DD HH:mm:ss'), updatedAt: moment(item.spec.updatedAt).format('YYYY-MM-DD HH:mm:ss') })); return ( <> {tdata && <PTable rowsSelection={{ onChange: onRowsSelectChange }} fields={fields} data={tdata} loading={loading}></PTable>} </> );

列选择

notion image
通常我们会需要对列表进行选择,然后进行操作,所以我们的Table组件需要提供选择的样式,以及选中之后的事件反馈,我们放在传入参数的rowsSelection字段,rows字段是一个对象,里面可以有关于选择的配置,和选中的参数
export interface RowsSelection<DataType> { onChange: (selectedRowIds: string[], selectedRows: DataType[]) => void; }
我们目前只导出一个被选中时的事件,事件返回被选中的所有data的id,以及所有被选中的数据