新接了个需求,要求可以拖拽表格的borer进行列宽调整。看到这个需求,感觉so easy, 印象中所有的UI组件库都支持这个功能,然后去看antd文档,懵逼了。。。。 4.0版本找不到这种功能支持,然后面向百度了一波,发现这种功能在antd 3.x版本里面,直接上链接。大家不要看到链接直接点走了哈,不行就先滑倒最下面,把注意事项看一下,然后再去看链接
antd 文档传送门 表格 Table - Ant Design
东西大差不差,4.x版本的antd也支持。个人实现代码如下,为了方便,TS方面避免了严格校验,由于用的地方较多,直接做了一个封装,封装如下
首先要下载依赖 npm install react-resizable --save ,然后重启项目。
import React, { PureComponent } from 'react';
import { Table } from 'antd';
import { Resizable } from 'react-resizable';
const ResizeableTitle = (props: { [x: string]: any; onResize: any; width: any; }) => {
const { onResize, width, ...restProps } = props;
if (!width) {
return <th {...restProps} />
}
return (
<Resizable width={width} height={0} onResize={onResize} draggableOpts={{ enableUserSelectHack: false }}>
<th {...restProps} />
</ Resizable >
)
}
class TableResize extends PureComponent<any, any> {
constructor(props: any) {
super(props);
}
state = {
columns: this.props.columns
};
components = {
header: {
cell: ResizeableTitle,
},
};
handleResize = (index: number) => (e: any, { size }: any) => {
this.setState(({ columns }: any) => {
const nextColumns = [...columns];
nextColumns[index] = {
...nextColumns[index],
width: size.width,
};
return { columns: nextColumns };
});
};
render() {
const columns = this.state.columns.map((col: any, index: number) => ({
...col,
onHeaderCell: (column: { width: any; }) => ({
width: column.width,
onResize: this.handleResize(index),
}),
}));
return <Table
components={this.components}
columns={columns}
rowKey="id"
border // 不要这个属性也有拖拽表示
pagination={false}
rowSelection={this.props.rowSelection} // 选中行的事件,不需要可删除
dataSource={this.props.dataSource}
onChange={(pagination: any, filters: any) => this.props.handleTableChange(pagination, filters)} /> //表格筛选功能触发的事件,不需要可删除
}
}
export default TableResize
使用地方如下
首先引入组件
import TableReszie from '@components/TableResize'
<TableReszie
dataSource={dataSource}
columns={columns}
loading={loading}
handleTableChange={handleTableChange}
/>
注意点:1.传入的columns一定要每列都要设置列宽,设置列宽属性 width:number,不然对应列的后面不会出现拖拽标识,或者出现了,但是不可拖拽
2. 封装的组件内部的Table组件一定要传 rowKey="id",不然报错。pagination={false} 禁止自带分页器。
3.一定要把文档的css粘贴到全局样式里,样式文档内有,代码如下。
4.一定要针对表头文字进行禁止用户选择,不然用户按住鼠标左键从文字滑动的时候,选中了文字,然后再去拖拽,会发现松了鼠标后,依然可以进行拖拽,所以禁止用户选中表头文字很重
CSS 全局样式如下
// 表格拖拽样式
.react-resizable {
position: relative;
background-clip: padding-box;
}
.react-resizable-handle {
position: absolute;
width: 10px;
height: 100%;
bottom: 0;
right: -5px;
cursor: col-resize;
z-index: 1;
}
// 禁止用户选中表头文字。
tr {
th {
user-select: none; /* Chrome and Opera */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
}
}
吐槽点:如果colums 内传的render jsx太复杂了话,稍微有点卡顿。所以渲染数据不要有太过复杂的处理哦