废话不多说,直接开干~~~~
1、安装组件所需依赖:
"react-dnd": "^10.0.2",
"react-dnd-html5-backend": "^10.0.2",
"immutability-helper": "^3.0.1",
2、组件全部代码如下<可直接复制使用>:
import React from 'react';
import {Table,} from 'antd';
import {DndProvider,DragSource,DropTarget,} from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import update from 'immutability-helper';
let dragingIndex = -1;
//判断2个数组是否相等
function ArrayIsEqual(arr1,arr2){
//如果2个数组对应的指针相同,那么肯定相等,同时也对比一下类型
if(arr1===arr2){
return true;
}else{
if(arr1.length!=arr2.length){
return false;
}else{
for(let i in arr1){
//循环遍历对比每个位置的元素
if(arr1[i]!=arr2[i]){
//只要出现一次不相等,那么2个数组就不相等
return false;
}
}
//for循环完成,没有出现不相等的情况,那么2个数组相等
return true;
}
}
}
class BodyRow extends React.Component {
render() {
const {isOver, connectDragSource, connectDropTarget, moveRow, ...restProps} = this.props;
const style = {...restProps.style, cursor: 'move'};
let {className} = restProps;
if (isOver) {
if (restProps.index > dragingIndex) {
className += ' drop-over-downward';
}
if (restProps.index < dragingIndex) {
className += ' drop-over-upward';
}
}
return connectDragSource(
connectDropTarget(<tr {...restProps} className={className} style={style} />),
);
}
}
const rowSource = {
beginDrag(props) {
dragingIndex = props.index;
return {
index: props.index,
};
},
};
const rowTarget = {
drop(props, monitor) {
const dragIndex = monitor.getItem().index;
const hoverIndex = props.index;
if (dragIndex === hoverIndex) {
return;
}
props.moveRow(dragIndex, hoverIndex);
monitor.getItem().index = hoverIndex;
},
};
const DragableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
}))(
DragSource('row', rowSource, connect => ({
connectDragSource: connect.dragSource(),
}))(BodyRow),
);
export default class DraftSortTable extends React.Component {
constructor(props) {
super(props);
this.state = {
DataSource: [],
props,
}
}
static getDerivedStateFromProps(nextProps, prevState) {
const {DataSource,Portion,} = nextProps;
const {props} = prevState;
if(DataSource && DataSource.length >= 0 && props && props.DataSource){
//当传入的 DataSource '不等于' State 中的 DataSource 时,更新 State
if(!ArrayIsEqual(DataSource,props.DataSource)){
return {
DataSource,
props : {
DataSource,
},
};
};
};
//否则不对 State 进行操作
return null;
};
Components = {
body: {
row: DragableBodyRow,
},
};
/**
* 表格拖拽函数
*/
MoveRow = (dragIndex, hoverIndex) => {
const {DataSource,} = this.state;
const dragRow = DataSource[dragIndex];
this.setState(
update(this.state, {
DataSource: {
$splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]],
},
}),
);
this.SyncDataSource();
};
/**
* 将新数组反传给父组件
*/
SyncDataSource = () =>{
const {DataSource,} = this.state;
if (this.props.SyncDataSource) {
this.props.SyncDataSource(DataSource,this.props.CGType,);
}
}
render() {
const {Columns,RowSelection,RowClassName,ClassName,RowKey,} = this.props;
const {DataSource,} = this.state;
return (
<DndProvider backend={HTML5Backend}>
<Table
bordered
rowKey={RowKey}
columns={Columns}
pagination={false}
className={ClassName}
dataSource={DataSource}
rowSelection={RowSelection}
rowClassName={RowClassName}
components={this.Components}
onRow={(record, index) => ({
index,
moveRow: this.MoveRow,
})}
/>
</DndProvider>
);
}
}
3、在需要用到拖拽表格组件的地方引用<具体地址以个人代码为准,建议写在components中>:
import DraftSortTable from "../../../components/DraftSortTable";
4、使用组件:
<DraftSortTable
CGType={1}
RowKey="ID"
RowSelection={rowSelectionAR}
Columns={columns_AR}
DataSource={ARList}
SyncDataSource = {this.SyncDataSource.bind(this)}
RowClassName={(record, index) => {
if (record.IsCite) {
return "Expire editRow"
}else {return "editRow"}
}}
/>
5、根据需要写 SyncDataSource 方法
比如将排序结果存起来等...
END
本文介绍了如何利用React封装一个可拖拽排序的表格组件。首先,安装相关依赖,然后提供组件的完整代码,接着在项目中引入组件,并调用SyncDataSource方法处理排序后的数据,例如保存排序结果。
451

被折叠的 条评论
为什么被折叠?



