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属性,覆盖表头元素
- 每次拖拽之后将最新的列宽度值设置为列的真实宽度值
https://github.com/react-component/table/blob/75ee0064e54a4b3215694505870c9d6c817e9e4a/src/interface.ts#L129
export interface TableComponents {
table?: CustomizeComponent;
header?: {
wrapper?: CustomizeComponent;
row?: CustomizeComponent;
cell?: CustomizeComponent;
};
body?:
| CustomizeScrollBody
| {
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 ;
}
return (
);
};
💎 覆盖表头组件
const ResizeTable = (
props: JSX.IntrinsicAttributes &
TableProps & { children?: React.ReactNode } & {
ref?: React.Ref | undefined;
},
) => {
const [columns, setColumns] = useState(props.columns ?? []);
return (
);
};
💎 动态的更新表格列宽度
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 ;
}
return (
);
};
const ResizeTable = (
props: JSX.IntrinsicAttributes &
TableProps & { children?: React.ReactNode } & {
ref?: React.Ref | 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 (
);
};
export default ResizeTable;
🎉 最后
RaETable 是我独立开发的antd基于table组件的一揽子生态集合,常常用于B端业务处理,在敏捷开发场景事半功倍,效果显著,希望可以帮助更多的开发者。