React 模板封装之拖曳模板 DragTable

前言

前面有介绍过 React 模板封装之基础模板 BaseTable 今天在原先模板的基础上实现一个拖曳模板 DragTable。

一、拖曳模板 DragTable

模板说明:

在原先模板的基础上实现一个进阶版的拖曳模板 DragTable。

效果展示:
以下是正在拖动中的效果
在这里插入图片描述
使用场景:
需要在表格中进行拖曳排序。

二、使用案例

参数说明

  1. modalList :配置接口对应的字段数据集。
  2. actions:配置接口功能,如配置增删改查接口(url、method、data等)。
  3. sortSuccess:默认排序接口逻辑是直接传排序后的 id 集合。如果还需要其他的参数或者接口排序逻辑不是这样,则可以使用 sortSuccess 回调函数处理排序接口逻辑。sortSuccess 是拖动排序成功之后的回调(将排序后的 id 集合作为参数)。
    需要注意的是在给 modalList 参数时一定要将唯一的 key,比如 id 放在第一列进行配置。因为 id 集合取的字段就是 modalList 集合中的第一列字段。

从以下的案例可知,除了配置之外,只需要写一行代码即可实现如上图的具备增删改查的文章管理功能。

import React from "react";
import BaseTable from "../../../../template/BaseTable/index";
const modalList= [
    {label:"栏目ID", field:"columnId",renderType:"Input",visible:true,writable:true,},
    {label:"栏目名称",field:"columnName",renderType:'Input',require:true,visible:true},
    {label:"栏目描述",field:"description",renderType:'Input',require:true,visible:true},      
] 
const actions = [
    {   status:"sort",
        name:'排序',
        url: "/admin/weeksPeriodicalColumn/sort",
        method: 'post',       
        showColumn:false,
        data:{
            columnId:"",           
        }
    },   
    {  status:"query",
        name:'查询',
        url: "/admin/weeksPeriodicalColumn/columnList",
        extraField:"list",
        method: 'post',       
        showColumn:false        
    }
];
function Columns(){
    return (
        <DragTable
              actions={actions}
              modalList={modalList}                       
            />
      );
}
export default Columns;

三、API 使用指南

参考 React 模板封装之基础模板 BaseTable

四、源代码

在 DragTable 目录中包含如下文件。

index.js

import React from "react";
import { DndProvider, useDrag, useDrop } from "react-dnd";
import HTML5Backend from "react-dnd-html5-backend";
import BaseTable from "../BaseTable/index";
import update from "immutability-helper";
import { editAPI } from "../commonApi";
import { useRef, useImperativeHandle } from "react";
const type = "DragableBodyRow";
const DragableBodyRow = ({
  index,
  moveRow,
  className,
  style,
  ...restProps
}) => {
  const ref = React.useRef();
  const [{ isOver, dropClassName }, drop] = useDrop({
    accept: type,
    collect: (monitor) => {
      const { index: dragIndex } = monitor.getItem() || {};
      if (dragIndex === index) {
        return {};
      }
      return {
        isOver: monitor.isOver(),
      };
    },
    drop: (item) => {
      moveRow(item.index, index);
    },
  });
  const [, drag] = useDrag({
    item: { type, index },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
  });
  drop(drag(ref));
  return (
    <tr
      ref={ref}
      className={`${className}${isOver ? dropClassName : ""}`}
      style={{ cursor: "move", ...style }}
      {...restProps}
    />
  );
};
const components = {
  body: {
    row: DragableBodyRow,
  },
};
const moveRow = (baseTableRef, props, dragIndex, hoverIndex) => {
  let that = baseTableRef.current;
  const { dataSource, setDataSource } = that;
  const dragRow = dataSource[dragIndex];
  let { modalList } = props;
  setDataSource((dataSource) => {
    let newData = update(dataSource, {
      $splice: [
        [dragIndex, 1],
        [hoverIndex, 0, dragRow],
      ],
    });
    let columnIdList = [];
    newData.map((item) => {
      columnIdList.push(item[modalList[0].field]);
    });
    const { sortSuccess } = props;
    if (sortSuccess) {
      //自定义调排序接口
      sortSuccess(columnIdList);
    } else {
      //默认调排序接口
      let { actions, modalList } = props;
      let action = actions.filter((item) => item.status === "sort")[0];
      let data = action.data;
      for (let i in data) {
        data[i] = columnIdList;
      }
      editAPI(action, modalList, data);
    }
    return newData;
  });
};
function DragTable(props, ref) {
  const { actions, modalList } = props;
  return (
    <DndProvider backend={HTML5Backend}>
      <BaseTable        
        actions={actions}
        modalList={modalList}     
        components={components}
        onRow={(record, index) => ({
          index,
          moveRow: moveRow.bind(this, baseTableRef, props),
        })}
      />
    </DndProvider>
  );
}
export default React.forwardRef(DragTable);

以上可能有部分关联的JS文件没贴出来,因文件太多,就不一一贴出,需要的请留言。

五、总结

注意1:
配置 modalList 时一定要将唯一key放在第一行。

注意2:
接口排序逻辑默认上传排序后的 id 集合即可。如果还需要上传其他字段或者是不一样的排序逻辑,则需要使用 sortSuccess 回调函数,在该函数中调用排序接口或者进行其他操作。

注意3:
排序主要依赖 react-dnd 和 react-dnd-html5-backend 这两个库,但是由于版本不同引入的对象可能会有所差异。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值