react 表格实现拖拽功能

项目背景 : react + ant

单纯实现拖拽确实不难 , 我的需求是根据后台接口返回 , 生成对应的父子表格 , 并只可以拖拽子的位置 , 如图



后台返回的数据结构 (pid为0说明是父 , 子的pid等于父的id , 说明是父的子)


1 , 我先转成了树形结构且自己加上了key (注意 : key一定得是唯一的 , 否则会出现第一列数据拖拽不动 , 其他列数据可以拖拽的bug)


2 , 生成对应的父子表格 , 父要有对应的子 , 如图


3 , 更改onDragEnd的逻辑 , 实现效果
首先用.findIndex+.some来寻找当前子所属的父元素 , 然后再在父元素中用arrayMove将子调整顺序 , 最后创建一个新的副本仅仅更新当前父元素的子(注意 : 很关键 , 否则数据不更新) , 实现效果

否则就会如下图 , 有拖拽无更新 (图不太清晰 , 但"三里屯一直最上方")



整体代码 
 

 

// 第一步的步骤 , 主要是生成我需要的树形结构和key , key很关键 , 必须唯一 !!!
const res = await getList()
    console.log('res', res)

    const parentRes = res.filter(item => item.parentId == 0)

    const parentRes1 = [
      ...new Map(parentRes.map(item => [item.locationId, item])).values()
    ] //拿到去重后的parentId为0且locationId不同的数据

    const parentRes2 = parentRes1.map((item, index) => ({
      ...item, // 保留原有属性
      children: [],
      key: item.locationId
    }))

    const sonRes = res.filter(item => item.parentId !== 0)
    const sonRes1 = sonRes.map((item, index) => ({
      ...item, // 保留原有属性

      key: item.locationId
    }))

    setSonData(sonRes1)

    //用俩个for循环遍历将sonRes根据parentId插入到对应的父节点children中
    for (let i = 0; i < sonRes1.length; i++) {
      for (let j = 0; j < parentRes2.length; j++) {
        if (sonRes1[i].parentId === parentRes2[j].locationId) {
          parentRes2[j].children.push(sonRes1[i])
        }
      }
    }

    //俩个for循环才能让children里的locationName也换成place
    for (let i = 0; i < parentRes2.length; i++) {
      parentRes2[i].place = parentRes2[i].locationName
      delete parentRes2[i].locationName
      for (let j = 0; j < parentRes2[i].children.length; j++) {
        parentRes2[i].children[j].place = parentRes2[i].children[j].locationName
        delete parentRes2[i].children[j].locationName
      }
    }

    console.log('data', parentRes2)

    setData(parentRes2)



// 第三步的逻辑
const onDragEnd = ({ active, over }) => {
    console.log('active', active)

    console.log('over', over)
    if (active.id !== over?.id) {
      setData(prevData => {
        // 寻找当前拖拽元素所属的父元素
        const parentIndex = prevData.findIndex(parent =>
          parent.children.some(child => child.key === active.id)
        )
        if (parentIndex !== -1) {
          const parent = prevData[parentIndex]

          // 在父元素的children中调整顺序
          const activeChildIndex = parent.children.findIndex(
            child => child.key === active.id
          )
          const overChildIndex = parent.children.findIndex(
            child => child.key === over?.id
          )
          if (activeChildIndex > -1 && overChildIndex > -1) {
            const newChildren = arrayMove(
              parent.children,
              activeChildIndex,
              overChildIndex
            )
            // 创建一个新的prevData副本,仅更新当前父元素的children
            const newData = [...prevData]
            newData[parentIndex] = { ...parent, children: newChildren }
   

            // 收集newData中所有对象的id和sort值传递给后端
            const updatedItems = newChildren.map(item => ({
              id: item.locationId,
              sort: item.sort
            }))

            getSortMethod({ sorts: updatedItems }) // 传递给后端

            return newData
          }
        }

        console.log('prevData', prevData)

        return prevData // 如果没有找到或无法处理,返回原数据
      })
    }
  }





// 这里是第二步的内容 , 生成对应的父子表格
{data.map((item, index) => {    

   return (
                <div key={item.key}>
                  <DndContext
                    modifiers={[restrictToVerticalAxis]}
                    onDragEnd={onDragEnd}
                  >
                    <SortableContext
                      items={SonData.map(i => i?.key)}
                      strategy={verticalListSortingStrategy}
                    >
                      <Table
                        rowKey='key'
                        columns={updatedColumns} // 确保此处的columns是根据item动态调整后的
                        dataSource={item.children} // 此处确保使用当前item的children作为dataSource
                        pagination={false}
                        components={{
                          body: {
                            row: Row1
                          }
                        }}
                        isSelectAll={isSelectAll}
                        rowSelection={{
                          ...rowSelection2,
                          selectedRowKeys: selectedRowKeys2,
                          checkStrictly
                        }}
                      />
                    </SortableContext>
                  </DndContext>
                </div>
              )
            })}


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/665562.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

异常(Exception)

捕获异常 public class test {public static void main(String [] args) {int[] arr {1,2,3,4,5};try {System.out.println(arr[10]);}catch (ArrayIndexOutOfBoundsException e) {//索引越界异常System.out.println("索引越界");}System.out.println("看看我是…

测试FaceRecognitionDotNet报错“Error deserializing object of type int”

FaceRecognitionDotNet宣称是最简单的.net人脸识别模块&#xff0c;其内部使用Dlib、DlibDotNet、OpenCVSharp等模块实现人脸识别&#xff0c;网上有不少介绍文章。实际测试过程中&#xff0c;在调用FaceRecognition.Create函数创建FaceRecognition实例对象时&#xff0c;会报如…

AI入门:普通人可以利用AI做什么?休闲时间赚点小钱?(含多种实践案例)

大家好&#xff0c;我是影子&#xff0c;一名AI编程深耕者。 最近&#xff0c;有很多 AI 小白问我&#xff0c;AI到底可以做些什么&#xff1f;对我们普通人能有哪些帮助&#xff1f; 在我看来&#xff0c;对于我们刚接触 AI 的小伙伴而言。我们可以利用 AI 为我们工作提效&…

构建 VPC 并启动 Web 服务器

实验 2&#xff1a;构建 VPC 并启动 Web 服务器 目标 完成本实验后&#xff0c;您可以&#xff1a; 创建 VPC。创建子网。配置安全组。在 VPC 中启动 EC2 实例。任务 1&#xff1a;创建 VPC 在本任务中&#xff0c;您将使用 VPC 向导在单个可用区中创建一个 VPC、一个互联网网关…

神经网络---卷积神经网络CNN

一、从前馈神经网络到CNN 前馈神经网络&#xff08;Feedforward Neural Networks&#xff09;是最基础的神经网络模型&#xff0c;也被称为多层感知机&#xff08;MLP&#xff09;。 它由多个神经元组成&#xff0c;每个神经元与前一层的所有神经元相连&#xff0c;形成一个“…

电子电气SCI期刊,中科院1区TOP,收稿范围广泛

一、期刊名称 IEEE Transactions on Smart Grid 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;工程技术 影响因子&#xff1a;9.6 中科院分区&#xff1a;1区 三、期刊征稿范围 IEEE Transactions on Smart Grid是一本跨学科期刊&#xff0c;旨在传播智…

Gbase 国产数据库

参考&#xff1a;参考&#xff1a; 5分钟学会Linux环境GBase 8t安装和部署 - 光洋山 - twt企业IT交流平台 (talkwithtrend.com)https://www.talkwithtrend.com/Article/197237 视频 GBase 8s快速入门-功能简介与演示-大数据教程-腾讯课堂 (qq.com)https://ke.qq.com/course/…

Qt 插件机制使用及原理

目录 1.引言 2.插件原理 3.插件实现 3.1.定义一个接口集(只有纯虚函数的类) 3.2.实现接口 4.插件的加载 4.1.静态插件 4.1.1.静态插件实现方式 4.1.2.静态插件加载的过程 4.1.3.示例 4.2.动态插件 4.2.1.动态插件的加载过程 5.定位插件 6.插件开发的优势 7.总结…

蓝桥杯高频考点-与日期相关的题目

文章目录 前言1. 如何枚举合法日期1.1 预存每个月的天数1.2 封装一个判断日期是否合法的函数1.3 枚举日期并判断日期是否合法 2. 判断日期是否为回文日期2.1 将日期当作字符串进行处理2.2 将日期当作一个8位数进行处理 3. 给定初始日期&#xff0c;计算经过n天后对应的日期3.1 …

Java集合【超详细】2 -- Map、可变参数、Collections类

文章目录 一、Map集合1.1 Map集合概述和特点【理解】1.2 Map集合的基本功能【应用】1.3 Map集合的获取功能【应用】1.4 Map集合的两种遍历方式 二、HashMap集合2.1 HashMap集合概述和特点【理解】2.2 HashMap的组成、构造函数2.3 put、查找方法2.4 HashMap集合应用案例【应用】…

另一棵树的子树(oj题)

一、题目链接 https://leetcode.cn/problems/subtree-of-another-tree/submissions/536304222 二、题目思路 1.首先遍历大树&#xff0c;判断大树的根结点的值是否等于小树的根结点的值&#xff0c;如果不相等&#xff0c;就找大树的左孩子或者右孩子&#xff0c;以左孩子为根…

博士毕业论文/CTEX/LATEX

LATEX环境安装 CTEX 安装 &#xff08;垃圾&#xff0c;不要装&#xff09; 运行 clean.batcomp.bat 缺少字体 Couldn’t find Adobe Heiti S.cfg’ miktex-maketfm: No creation rule for font “Adobe Heiti Std”.解决方法&#xff1a;其实就是下载这四个字体之后&…

jsp实验19 File

三、源代码以及执行结果截图&#xff1a; readJSPFile.jsp <% page contentType"text/html" %> <% page pageEncoding "utf-8" %> <% page import"java.io.*"%> <style> #tom{ font-family:宋体;font-size:2…

Crosslink-NX器件应用连载(10): 图像输入并通过HDMI输出

作者&#xff1a;Hello,Panda 大家下午好&#xff0c;晚上好。这里分享一个Lattice Crosslink-NX器件通过MIPI或LVDS输入图像&#xff0c;并通过HDMI输出图像的案例&#xff08;其实这是个比较冷门的需求&#xff0c;Crosslink-NX器件还是主要做MIPI桥接用&#xff09;。 咱们…

《Kubernetes部署篇:基于麒麟V10+ARM64架构部署harbor v2.4.0镜像仓库》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;企业级K8s集群运维实战 一、环境信息 K8S版本 操作系统 CPU架构 服务版本 1.26.15 Kylin Linux Advanced Server V10 ARM64 harbor v2.4.0 二、部…

文刻创作AI工具怎么注册卡密

在科技日新月异的今天&#xff0c;生成式人工智能&#xff08;AI&#xff09;的迅猛发展正在重塑各行各业的面貌。其中&#xff0c;文刻创作AI工具以其独特的魅力和强大的功能&#xff0c;成为了内容创作领域的一股清流&#xff0c;引领着内容生产的新潮流。 【文刻二创工具教…

人脸识别模型与人类视觉识别的对比——评估人脸识别模型存在偏见是否比人类的偏见大?

1. 概述 人脸识别系统是一个几十年来一直备受关注的研究领域。而且在过去的几年中。公司和政府一直在积极引入人脸识别系统&#xff0c;并且我们看到越来越多的机会可以看到人脸识别系统。例如&#xff0c;有的系统可以随便介绍&#xff0c;如搜索特定人的图像&#xff08;图像…

SAP Build引言

前言 SAP Build 似乎是一个整合了很多低代码或无代码产品的平台&#xff0c;最早的时候应该都是各自分开的几个产品&#xff0c;近年合并到一块上了SAP Build平台 现在看官网的介绍应该是有三四个产品被集成进来了&#xff0c;分别是SAP IRPA&#xff0c;SAP Workflow&#xf…

K8s Ingress 详解

文章目录 K8s Ingress 详解Ingress 资源清单Ingress 基于URL 实现路由Ingress 基于名称虚拟主机Ingress 实现HTTPS创建TLS 证书创建Secrets配置ingress Ingress RewriteIngress 灰度发布Ingress 配置认证 K8s Ingress 详解 Ingress 资源清单 apiVersion: networking.k8s.io/v…

编程学习 (C规划) 6 {24_4_18} 七 ( 简单扫雷游戏)

首先我们要清楚扫雷大概是如何实现的&#xff1a; 1.布置雷 2.扫雷&#xff08;排查雷&#xff09; &#xff08;1&#xff09;如果这个位置是雷就炸了&#xff0c;游戏结束 &#xff08;2&#xff09;如果不是雷&#xff0c;就告诉周围有几个雷 3.把所有不是雷的位置都找…