表格拖拽

82 阅读1分钟

安装 npm install react-dnd react-dnd-html5-backend

import React, { useState } from 'react';
import { Form } from 'antd';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { useDrag, useDrop } from 'react-dnd';

// 拖拽源逻辑
const DraggableRow = ({ index, children }) => {
  const [, drag] = useDrag({
    type: 'ROW',
    item: { index },
  });

  return (
    <tr ref={drag}>
      {children}
    </tr>
  );
};

// 拖拽目标逻辑
const DroppableTableRow = ({ index, children, moveRow }) => {
  const [, drop] = useDrop({
    accept: 'ROW',
    hover: (item) => {
      if (item.index !== index) {
        moveRow(item.index, index);
        item.index = index;
      }
    },
  });

  return (
    <tr ref={drop}>
      {children}
    </tr>
  );
};

// 主表单组件
const MyForm = () => {
  const [dataSource, setDataSource] = useState([
    { key: 1, name: 'John', age: 28 },
    { key: 2, name: 'Jim', age: 32 },
    { key: 3, name: 'Joe', age: 25 },
  ]);

  const moveRow = (fromIndex, toIndex) => {
    const updatedData = [...dataSource];
    const [removed] = updatedData.splice(fromIndex, 1);
    updatedData.splice(toIndex, 0, removed);
    setDataSource(updatedData);
  };

  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Age</th>
        </tr>
      </thead>
      <tbody>
        {dataSource.map((data, index) => (
          <DroppableTableRow key={data.key} index={index} moveRow={moveRow}>
            <DraggableRow index={index}>
              <td>{data.name}</td>
              <td>{data.age}</td>
            </DraggableRow>
          </DroppableTableRow>
        ))}
      </tbody>
    </table>
  );
};

// 包裹表单组件
export default Form.create()(props => (
  <DndProvider backend={HTML5Backend}>
    <MyForm {...props} />
  </DndProvider>
));