基于React dnd实现列表list拖拽排序

1,260 阅读1分钟

基于react-dnd,react-dnd-html5-backend两个依赖实现。

以下是react class组件的实现方式:

  1. 定义父组件容器List,只有被该组件包裹的子组件才可拖拽。

    import React, { PureComponent } from 'react';import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import update from 'immutability-helper'; import ListItem from './ListItem.jsx';

    export default class List extends React.Component{ render(){
    return (

    //...

    ) } }

2.实现拖拽子组件ListItem,该组件为拖拽单元。

import React from 'react';
import { DragSource, DropTarget } from 'react-dnd';// DragSource的相关设定
const dragSourceSpec = {    
   beginDrag(props) {        
      return {         
        index: props.index        };    
    },    
   canDrag(props, monitor){        
     return true;   
   }}
const dragSourceCollect = (connect, monitor) => {    
   return {        
     connectDragSource: connect.dragSource(),        
     isDragging: monitor.isDragging()    };
};
// DragTarget的相关设定
const dragTargetSpec = {    
   drop(props, monitor) {      
     const { dragSort } = props;     
     const { index } = monitor.getItem();
      // 真正的拖拽逻辑!!!!!!        
     dragSort && dragSort(index, hoverIndex);        
     monitor.getItem().index = hoverIndex;     
     }    
    },    
   canDrop(props, monitor) {        
     return true;    
}};
const dragTargetCollect = (connect, monitor) => {    
  return {        
    connectDropTarget: connect.dropTarget(),        
    canDrop: monitor.canDrop(),        
    isOver:monitor.isOver(), //source是否在Target上方        
    isOverCurrent: monitor.isOver({ shallow: true }),        
    itemType: monitor.getItemType()//获取拖拽组件type    };
}

class ListItem extends React.Component{    
  render(){        
   const { iteration, connectDragSource, connectDropTarget } = this.props;        
   return connectDragSource(            
     connectDropTarget(                
       <div>                
       </div>            
       )      
    );    
}}

const Demo= DragSource('demo', dragSourceSpec, dragSourceCollect)(ListItem);
export default DropTarget('demo', dragTargetSpec, dragTargetCollect)(Demo);