React 拖动排序

157 阅读1分钟

1、安装依赖

yarn add react-dnd react-dnd-html5-backend

2、新增拖动组件

const ReactDndDragSort = ({
  row,  // 当前可拖动dom 的数据 
  index, //  当前数据排序index
  changePosition = () => { }, // 拖动后触发
  className = "",
  children, // 可拖动dome展示
  isDrop = true // 是否可拖动,可控制该属性 设置拖动区域
}) => {
 
  const ref: any = useRef(null);
  const [{ isOver, dropClassName }, drop] = useDrop({
    accept: "DragDropBox", // 只对useDrag的type的值为DragDropBox时才做出反应
    collect: monitor => {
      const { index: dragIndex } = monitor.getItem() || {};
      if (dragIndex === index) {
        return {};
      }
      return {
        isOver: monitor.isOver(),
        dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward',
      };
    },
    drop: (item: { index: number, row: any }) => {
      changePosition(item.row, index);
    },
    hover: (item: any, monitor: any) => {

    },
  });

  const [{ isDragging }, drag] = useDrag(() => ({
    type: isDrop ? 'DragDropBox' : '',
    item: { type: "DragDropBox", index, row },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
    canDrag: (monitor) => true
  }), [isDrop])

  const changeRef = drag(drop(ref))



  return (
    <div
      //@ts-ignore
      ref={changeRef}
      style={{ opacity: isDragging ? 0.5 : 1, cursor: isDrop ? 'move' : 'auto' }}
      className={`${className}${isOver ? dropClassName : ''}`}
    >
      <span >
        {children}
      </span>
    </div>
  );
};

3、拖动变化并未使用 index 只使用存储数据,及拖动后位置index 可在拖动变化方法中操作数据

    const data = cloneDeep(list)
    const index = data.findIndex((v: any) => v.id === item.id)
    if (index === hoverIndex) return
    data.splice(index, 1)
    data.splice(hoverIndex, 0, item)
    console.log(data)