raETable
是react
antd
Easy Table 的缩写。旨在让开发者在react
中使用 antd
的Table
时更 easy。
❝Github: https://github.com/mmdctjj/raetable
npm: https://www.npmjs.com/package/raetable
文档:https://mmdctjj.github.io/raetable
❞
🚀 变更内容
最近工作的需求变动,antd表格的宽度需要支持拖动调整。
调研了一圈,呼声最高的方案是使用react-resizable
库实现。
实现之后发现这个功能特别适合 RaETable
于是,我也给这个组件增加了这个功能。不过,不用担心,这个功能默认是关闭的,当你设置resize
为 true
时才会开启该功能。
效果可以直接看这个示例
录制的工具限制,只有15帧动画,感兴趣的话可以到官网实际操作下。
https://mmdctjj.github.io/raetable/components/e-table#表格宽度自适应
🚀 实现原理
实现原理:
react-resizable
提供了Resizable
组件用于包括th
元素,成为可以拖拽的元素。- 采用
antd``Table
组件提供的components
属性,覆盖表头元素 - 每次拖拽之后将最新的列宽度值设置为列的真实宽度值
export interface TableComponents<RecordType> { table?: CustomizeComponent; header?: { wrapper?: CustomizeComponent; row?: CustomizeComponent; cell?: CustomizeComponent; }; body?: | CustomizeScrollBody<RecordType> | { wrapper?: CustomizeComponent; row?: CustomizeComponent; cell?: CustomizeComponent; }; }
🚀 实现过程
💎 重写表头组件
import { Resizable, ResizeCallbackData } from 'react-resizable'; import 'react-resizable/css/styles.css'; const ResizableTitle = (props: { [x: string]: any; onResize: ((e: React.SyntheticEvent, data: ResizeCallbackData) => any) | undefined; width: number; }) => { const { onResize, width, ...restProps } = props; if (!width) { return <th {...restProps} />; } return ( <Resizable width={width} height={0} onResize={onResize}> <th {...restProps} /> </Resizable> ); };
💎 覆盖表头组件
const ResizeTable = ( props: JSX.IntrinsicAttributes & TableProps<any> & { children?: React.ReactNode } & { ref?: React.Ref<HTMLDivElement> | undefined; }, ) => { const [columns, setColumns] = useState(props.columns ?? []); return ( <Table {...props} columns={columns} components={{ header: { cell: ResizableTitle, }, }} scroll={{ x: 'max-content' }} // 添加滚动条以适应自适应宽度 /> ); };
💎 动态的更新表格列宽度
const handleResize = (index: number) => (event: any, { size }: any) => { setColumns((prevColumns) => { const nextColumns = [...prevColumns]; nextColumns[index] = { ...nextColumns[index], width: size.width, }; return nextColumns; }); }; const resizableColumns = columns?.map((col: any, index: number) => ({ ...col, onHeaderCell: (column: { width: number }) => ({ width: column.width, onResize: handleResize(index), }), }));
完整代码如下
import { Table, TableProps } from 'antd'; import React, { useState } from 'react'; import { Resizable, ResizeCallbackData } from 'react-resizable'; import 'react-resizable/css/styles.css'; const ResizableTitle = (props: { [x: string]: any; onResize: ((e: React.SyntheticEvent, data: ResizeCallbackData) => any) | undefined; width: number; }) => { const { onResize, width, ...restProps } = props; if (!width) { return <th {...restProps} />; } return ( <Resizable width={width} height={0} onResize={onResize}> <th {...restProps} /> </Resizable> ); }; const ResizeTable = ( props: JSX.IntrinsicAttributes & TableProps<any> & { children?: React.ReactNode } & { ref?: React.Ref<HTMLDivElement> | undefined; }, ) => { const [columns, setColumns] = useState(props.columns ?? []); const handleResize = (index: number) => (event: any, { size }: any) => { setColumns((prevColumns) => { const nextColumns = [...prevColumns]; nextColumns[index] = { ...nextColumns[index], width: size.width, }; return nextColumns; }); }; const resizableColumns = columns?.map((col: any, index: number) => ({ ...col, onHeaderCell: (column: { width: number }) => ({ width: column.width, onResize: handleResize(index), }), })); return ( <Table {...props} columns={resizableColumns} components={{ header: { cell: ResizableTitle, }, }} scroll={{ x: 'max-content' }} // 添加滚动条以适应自适应宽度 /> ); }; export default ResizeTable;
🎉 最后
RaETable
是我独立开发的antd
基于table
组件的一揽子生态集合,常常用于B端业务处理,在敏捷开发场景事半功倍,效果显著,希望可以帮助更多的开发者。
如果你在使用中有任何的问题,都可以联系我。
好了,今天的分享就这些,文章中错误的地方欢迎指正。