React 模板封装之拖曳模板 DragTable

React 模板封装之拖曳模板 DragTable

  • 前言
  • 一、拖曳模板 DragTable
  • 二、使用案例
  • 三、API 使用指南
  • 四、源代码
  • 五、总结

前言

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

一、拖曳模板 DragTable

模板说明:

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

效果展示:
以下是正在拖动中的效果
React 模板封装之拖曳模板 DragTable_第1张图片
使用场景:
需要在表格中进行拖曳排序。

二、使用案例

参数说明

  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 "utils/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 这两个库,但是由于版本不同引入的对象可能会有所差异。

你可能感兴趣的:(#,React,通用组件封装)