raETable
是react
antd
Easy Table 的缩写。旨在让开发者在react
中使用 antd
的Table
时更 easy。
Github: github.com/mmdctjj/rae...
往期回顾
🚀 变更内容
最近工作的需求变动,antd表格的宽度需要支持拖动调整。
调研了一圈,呼声最高的方案是使用react-resizable
库实现。
实现之后发现这个功能特别适合 RaETable
于是,我也给这个组件增加了这个功能。不过,不用担心,这个功能默认是关闭的,当你设置resize
为 true
时才会开启该功能。
效果可以直接看这个示例
录制的工具限制,只有15帧动画,感兴趣的话可以到官网实际操作下。
mmdctjj.github.io/raetable/co...
🚀 实现原理
实现原理:
react-resizable
提供了Resizable
组件用于包括th
元素,成为可以拖拽的元素。- 采用
antd``Table
组件提供的components
属性,覆盖表头元素 - 每次拖拽之后将最新的列宽度值设置为列的真实宽度值
js
export interface TableComponents<RecordType> {
table?: CustomizeComponent;
header?: {
wrapper?: CustomizeComponent;
row?: CustomizeComponent;
cell?: CustomizeComponent;
};
body?:
| CustomizeScrollBody<RecordType>
| {
wrapper?: CustomizeComponent;
row?: CustomizeComponent;
cell?: CustomizeComponent;
};
}
🚀 实现过程
💎 重写表头组件
js
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>
);
};
💎 覆盖表头组件
js
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' }} // 添加滚动条以适应自适应宽度
/>
);
};
💎 动态的更新表格列宽度
js
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),
}),
}));
完整代码如下
js
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端业务处理,在敏捷开发场景事半功倍,效果显著,希望可以帮助更多的开发者。
如果你在使用中有任何的问题,都可以联系我。
好了,今天的分享就这些,文章中错误的地方欢迎指正。