最近项目中要做一个拖动排序功能,首先想到的是之前项目中用过的antd自带的tree和table的拖动排序,但是只能在对应的组建里使用。这里用的是自定义组件,随意拖动排序,所以记录一下实现流程
react-dnd antd组件的拖动排序都是用的这个库,使用比较灵活,但是要配置的东西比较多,需求复杂时使用这个库;
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;
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
// Time to actually perform the action
props.moveRow(dragIndex, hoverIndex);
// Note: we're mutating the monitor item here!
// Generally it's better to avoid mutations,
// but it's good here for the sake of performance
// to avoid expensive index searches.
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),
);
<DndProvider backend={HTML5Backend}>
<Table
columns={columns}
dataSource={this.state.data}
components={this.components}
onRow={(record, index) => ({
index,
moveRow: this.moveRow,
})}
/>
</DndProvider>
react-beautiful-dnd 在项目中看到引用了这个库,使用起来也不算复杂,就试着用了这个库,不过只支持水平或垂直拖动,一行或者一列元素时可以使用,可惜这个需求时两行多列元素,也没办法用;<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId='phone-droppable'>
{droppableProvided => (
<div ref={droppableProvided.innerRef} {...droppableProvided.droppableProps}>
{this.state.phoneImages.map((image, index) => (
<Draggable key={image||'upload'} draggableId={image||'upload'} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={{
...provided.draggableProps.style,
opacity: snapshot.isDragging ? 0.8 : 1,
display: 'inline-block'
}}
>
<img src={img}/>
</div>
)}
</Draggable>
))}
{droppableProvided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
react-sortable-hoc 最后在网上搜索的时候,又看到这个库,使用起来比较简单,使用SortableList包裹要拖拽元素的容器,SortableElement包裹要拖拽的子元素,设置容器拖拽方向axis={'xy'}
即可使grid布局的多个元素支持水平和竖直方向拖动排序;const SortableItem = SortableElement(({children}) => (
<div>{children}</div>
));
const SortableList = SortableContainer(({children}) => {
return (
<div style={{display: 'grid', gridTemplateRows: '117px 117px', gridTemplateColumns: '120px 120px 120px 120px'}}>
{children}
</div>
);
});
<SortableList onSortEnd={this.onPadSortEnd} helperClass={Styles.sortableHelper} axis={'xy'}>
{this.state.padImages.map((image, index) => (
<SortableItem key={`pad-item-${index}`} index={index} className={Styles.sortableItem}>
<img src={img}/>
</SortableItem>
))}
</SortableList>
好久没更新博客了,最近工作比较忙,差不多每天都要加班,中间有经历搬家,没时间坐下来总结学到的东西。工作的时候因为这块花费了一些时间,想到可能别人也会遇到类似问题,所以就记录下来了
到此这篇关于react实现记录拖动排序的文章就介绍到这了,更多相关react记录拖动排序内容请搜索软件开发网以前的文章或继续浏览下面的相关文章希望大家以后多多支持软件开发网!