react Dnd结合antd table实现跨表格拖拽放置和组内拖拽改变顺序功能

react Dnd结合antd table实现跨表格拖拽放置和组内拖拽改变顺序

封装通用的可拖拽表格

import React, { useState, useCallback, useRef, useEffect } from 'react';

import { DndProvider, useDrag, useDrop } from 'react-dnd';

import { HTML5Backend } from 'react-dnd-html5-backend';

import { message, Table } from 'antd';

import update from 'immutability-helper';

const ItemTypes = {
  ROW: 'row',
};

function DragTable(props) {
  const {
    dataSource,
    columns,
    onChange,
    is,
    k,
    rowSelection,
    pagination,
    ...tableProps
  } = props;

  const [list, setList] = useState([]);
  const [error, setError] = useState('');

  useEffect(() => {
    setList(dataSource);
  }, [dataSource]);

  const handleDrag = useCallback(
    (col, hoverIndex) => {
      if (k !== col.record.key) {
        console.log(k, col.record.key);
        message.error('不同库不允许操作');
        return;
      }

      let dragItem = col.record;
      let newList = [];

      let flag = list.some((v, i) => {
        if (v.id === dragItem.id) {
          return true;
        } else {
          return false;
        }
      });

      if (flag) {
      //组内交换顺序
        newList = update(list, {
          $splice: [
            [col.index, 1],
            [hoverIndex, 0, dragItem],
          ],
        });
      } else {
        //跨表格拖拽
        newList = [...list];
        newList.splice(hoverIndex, 0, dragItem);
      }

      setList(newList);
      onChange(newList, dragItem, is, k, flag);
    },

    [list]
  );

  const DraggableRow = (props) => {
    const {
      index,
      record,
      handleDrag,
      rowSelection,
      pagination,
      ...restProps
    } = props;

    const ref = useRef(null);

    // 接收
    const [{ isOver, canDrop }, drop] = useDrop({
      accept: ItemTypes.ROW,

      drop: (col) => handleDrag(col, index),

      canDrop: (item) => {
        setError(undefined);
        const filter = list.filter((it) => it.id === item.id);
        if (!!filter.length) {
          setError('数据已经被放置');
          return false;
        }
        return true;
      },

      collect: (monitor) => ({
        isOver: monitor.isOver(),
        canDrop: monitor.canDrop(),
      }),
    });

    const rowStyle = { ...restProps.style };

    if (isOver && canDrop) {
      rowStyle.background = '#f0f4f8';
    }

    // 拖拽
    const [{ isDragging }, drag] = useDrag({
      // item: { type: ItemTypes.ROW, record, index },
      type: ItemTypes.ROW,
      item: () => {
        return { record, index };
      },
      collect: (monitor) => ({
        isDragging: monitor.isDragging(),
      }),
    });

    const opacity = isDragging ? 0 : 1;

    drag(drop(ref));

    return ;
  };

  const components = {
    body: {
      row: DraggableRow,
    },
  };

  return (
    
       ({
          record,
          index,
          handleDrag,
        })}
      />
    
  );
}

export default DragTable;

import DragTable from './dragTable';

 handleTableDrag = (newList, dragItem, is, k, flag) => {
    let arr = deepClone(this.state.list) || [];
    let d = arr.filter((v) => v.key === k)?.[0]?.data;

    if (flag) {
      //组内交换顺序,赋新值
      d[is].libraryList = newList;
    } else {
       //跨表格拖拽
      d = d.map((v, i) => {
        v.libraryList = v.libraryList.filter((vs, is) => {
          return vs.id !== dragItem.id;
        });
        return v;
      });
      d[is].libraryList = newList;
    }
    this.setState({ list: arr });
  };
  

你可能感兴趣的:(react.js,前端,前端框架)