react ant 表格实现 拖拽排序和多选

项目背景 : react + ant
要实现 : 有多选功能(实现批量删除 , 也可以全选) + 可以拖拽(可以复制 , 方便顶部的搜索功能)
要实现效果如下

1 这是最初的拖拽功能实现 , 不能复制表格里的内容 , 不符合要求

2 更改了ROW的内容 , 实现了可以复制表格内容
代码

//控制是否可以选中表格里的文字
const Row1 = props => {
  const {
    attributes,
    listeners,
    setNodeRef,
    setActivatorNodeRef,
    transform,
    transition,
    isDragging
  } = useSortable({
    id: props['data-row-key']
  })
  const style = {
    ...props.style,
    transform: CSS.Translate.toString(transform),
    transition,
    ...(isDragging
      ? {
          position: 'relative',
          zIndex: 9999
        }
      : {})
  }
  const contextValue = useMemo(
    () => ({
      setActivatorNodeRef,
      listeners
    }),
    [setActivatorNodeRef, listeners]
  )
  return (
    <RowContext.Provider value={contextValue}>
      <tr {...props} ref={setNodeRef} style={style} {...attributes} />
    </RowContext.Provider>
  )
}




3 多选功能ant官网也只提供了rowSelection方法 , 而rowSelection的位置总是在表格最左边 , 我需要让拖拽icon在最左边 , 多选功能在icon右边 , 目前问题如下


 









 

解决思路 : 舍弃了官网的rowSelection方法 , 添加自定义选择列

代码分为俩部分 , 一部分是父页面 , ( 父页面代码太多只显示了功能代码 )

 

import React, { useContext, useMemo, useState, useEffect } from 'react'
import { HolderOutlined } from '@ant-design/icons'
import { DndContext } from '@dnd-kit/core'
import { restrictToVerticalAxis } from '@dnd-kit/modifiers'
import {
  arrayMove,
  SortableContext,
  useSortable,
  verticalListSortingStrategy
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
const RowContext = React.createContext({})


//控制是否可以选中表格里的文字
const Row1 = props => {
  const {
    attributes,
    listeners,
    setNodeRef,
    setActivatorNodeRef,
    transform,
    transition,
    isDragging
  } = useSortable({
    id: props['data-row-key']
  })
  const style = {
    ...props.style,
    transform: CSS.Translate.toString(transform),
    transition,
    ...(isDragging
      ? {
          position: 'relative',
          zIndex: 9999
        }
      : {})
  }
  const contextValue = useMemo(
    () => ({
      setActivatorNodeRef,
      listeners
    }),
    [setActivatorNodeRef, listeners]
  )
  return (
    <RowContext.Provider value={contextValue}>
      <tr {...props} ref={setNodeRef} style={style} {...attributes} />
    </RowContext.Provider>
  )
}

//拖拽图标
const DragHandle = () => {
  const { setActivatorNodeRef, listeners } = useContext(RowContext)
  return (
    <Button
      type='text'
      size='small'
      icon={<HolderOutlined />}
      style={{
        cursor: 'move'
      }}
      ref={setActivatorNodeRef}
      {...listeners}
    />
  )
}

function role () {
  //被拖拽后请求接口和数据改变
  const onDragEnd = ({ active, over }) => {
    if (active.id !== over?.id) {
      setData(data => {
        const activeIndex = data.findIndex(item => item?.key === active.id)
        const overIndex = data.findIndex(item => item?.key === over?.id)

        const newData = arrayMove(data, activeIndex, overIndex).map(
          (item, index) => ({
            ...item,
            sort: data.length - index
          })
        )

        // 收集newData中所有对象的id和sort值
        const updatedItems = newData.map(item => ({
          id: item.roleId,
          sort: item.sort
        }))

        getSortMethod({ sorts: updatedItems }) //后端接口

        return arrayMove(data, activeIndex, overIndex)
      })
    }
  }

  // 让拖拽icon在左侧
  const columns = [
    {
      width: 60,
      render: () => <DragHandle />
    },
    ...]


  return (
    <>
       <DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
          <SortableContext
            items={data.map(i => i?.key)}
            strategy={verticalListSortingStrategy}
          >
            {TableComSelect1({
              loading,
              data,
              columns,
              onSelectionChange: handleSelectionChange, // 选中的表格数量信息传递给表格
              isSelectAll: isSelectAll, //是否全选

              rowKey: 'key', //拖拽
              components: {  //拖拽
                body: {
                  row: Row1
                }
              }
            })}
          </SortableContext>
        </DndContext>
    </>
  )
}

export default role




另一部分是封装的表格组件 ( 全部代码如下 )

import React, { useState, useEffect, useContext } from 'react'
import { Table, Button, Checkbox } from 'antd'

import SimpleBar from 'simplebar-react'

import 'simplebar/dist/simplebar.min.css' // 引入 simplebar 的样式
import './index.less'
import { useTranslation } from 'react-i18next' // 引入 useTranslation 钩子
import i18n from '@/utils/i18n' //国际化组件

const TableComSelect1 = props => {
  const { t } = useTranslation() // 获取翻译函数和语言切换函数

  const [obj, setObj] = useState({})
  const {
    components,
    rowKey,
    columns = [],
    data = [],
    loading = false,
    onSelectionChange,
    isSelectAll
  } = props
  const [selectedRowKeys, setSelectedRowKeys] = useState([]) //让批量删除后不被选中
  const [selectionType, setSelectionType] = useState('checkbox')

  //接收父传递的key 用来控制表格选中
  const onSelectChange = newSelectedRowKeys => {
    console.log('selectedRowKeys changed: ', newSelectedRowKeys)
    setSelectedRowKeys(newSelectedRowKeys) //让子表格可以选中
    onSelectionChange(newSelectedRowKeys) //将选中的子表格选中的key值赋给父组件
  }
  //旧的选择功能,一直在最左侧
  const rowSelection = {
    selectedRowKeys,
    onChange: onSelectChange
  }

  // 点击全选
  useEffect(() => {
    if (isSelectAll) {
      setSelectedRowKeys(data.map(item => item.key))
    } else {
      setSelectedRowKeys([])
    }
  }, [isSelectAll])

  // 创建一个自定义的选择列
  const selectionColumn = {
    width: '100px',
    title: t('select'), // 或者根据需要设置标题
    fixed: 'left', // 如果需要固定列,请保留此行
    render: (_, record) => (
      <Checkbox
        checked={selectedRowKeys.includes(record[rowKey])} // 假设rowKey是用于唯一标识记录的字段
        onChange={() => {
          const newSelectedRowKeys = [...selectedRowKeys]
          if (newSelectedRowKeys.includes(record[rowKey])) {
            newSelectedRowKeys.splice(
              newSelectedRowKeys.indexOf(record[rowKey]),
              1
            )
          } else {
            newSelectedRowKeys.push(record[rowKey])
          }
          setSelectedRowKeys(newSelectedRowKeys)
          onSelectionChange(newSelectedRowKeys) // 更新父组件的选中项
        }}
      />
    )
  }

  // 在columns数组的第二位插入自定义的选择列
  const updatedColumns = [
    ...columns.slice(0, 1), // 取前一列
    selectionColumn, // 插入选择列
    ...columns.slice(1) // 取剩余列
  ]

  return (
    <div className='TableComSelect1'>
      <SimpleBar
        style={{ maxHeight: '600px', overflowY: 'auto', display: 'block' }}
        className='SimpleBar'
      >
        <Table
          components={components} // 应用自定义行组件等
          rowKey={rowKey} // 设置行键
          columns={updatedColumns}
          dataSource={data}
          loading={loading}
          pagination={false}
          // rowSelection={{ //旧的选择功能会一直在表格最左边
          //   ...rowSelection,
          //   type: selectionType,
          //   columnTitle: t('select'),
          //   columnWidth: '100px'
          // }}
          scroll={{
            x: 1700
          }}
        ></Table>
      </SimpleBar>
    </div>
  )
}
export default TableComSelect1

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

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

相关文章

Oracle数据库操作问题汇总

一、简介 Oracle Database&#xff0c;又名Oracle RDBMS&#xff0c;或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是世界上流行的关系数据库管理系统&#xff0c;系统可移植性好、使用方便、功能强&…

数据结构--二叉树--顺序存储判断是否二叉搜索树(2022统考真题)

数据结构–二叉树–顺序存储判断是否二叉搜索树(2022统考真题) 题目描述&#xff1a; 思路 二叉搜索树&#xff08;Binary Search Tree&#xff0c;简称BST&#xff09;是一种具有以下性质的二叉树&#xff1a; 对于树中的每个节点 N&#xff0c;它的左子树&#xff08;如果…

重学java 49 List接口

但逢良辰&#xff0c;顺颂时宜 —— 24.5.28 一、List接口 1.概述: 是collection接口的子接口 2.常见的实现类: ArrayList LinkedList Vector 二、List集合下的实现类 1.ArrayList集合的使用及源码分析 1.概述 ArrayList是List接口的实现类 2.特点 a.元素有序 —> 按照什么顺…

Oracle中rman的增量备份使用分享

继上次使用RMAN的全量备份和异机还原以后&#xff0c;开始研究一下增量备份和还原的方法。相比于全量RMAN的备份还原&#xff0c;增量的备份还原就相对简单。本实践教程直接上操作&#xff0c;还是回归到一个问题&#xff0c;就是关于两个数据库创建时候&#xff0c;必须保持or…

【职业教育培训机构小程序】教培机构“招生+教学”有效解决方案

教培机构“招生教学”有效解决方案在数字化转型的浪潮中&#xff0c;职业教育培训机构面临着提升教学效率、拓宽招生渠道、增强学员互动等多重挑战。小程序作为一种新兴的移动应用平台&#xff0c;为解决这些痛点提供了有效途径。 一、职业教育培训机构小程序的核心功能 &…

SpringBoot自动装配源码

自动装配&#xff1a; 实际上就是如何将Bean自动化装载到IOC容器中管理&#xff0c;Springboot 的自动装配时通过SPI 的方式来实现的 SPI&#xff1a;SpringBoot 定义的一套接口规范&#xff0c;这套规范规定&#xff1a;Springboot 在启动时会扫描外部引用 jar 包中的META-IN…

栈(从数据结构的三要素出发)

文章目录 逻辑结构物理结构顺序栈链栈共享栈 数据的操作顺序栈的基本操作链栈的基本操作共享栈的基本操作 数据结构的应用栈在括号匹配中的应用栈在表达式求值中的应用栈在递归调用中的应用 逻辑结构 栈是只允许在一端进行插入或删除操作的线性表。首先栈是一种线性表&#xf…

保留两位小数不四舍五入,10000.55变成10000.54的坑

正解 function moneyFormat(num){ let money num "";//隐式转换为字符串和toString()效果一样//没有小数补齐这个0if(money.indexOf(".")"-1"){moneymoney".00";}else{//有小数截取前二位小数moneymoney.substring(0,money.inde…

工业AI的崛起,中国自主创新的新机遇

我们都知道&#xff0c;互联网已经深刻地改变了我们的生活方式&#xff0c;催生了无数的新型商业模式和创新产业&#xff0c;推动了社会的经济变革。中国在互联网领域的发展取得了举世瞩目的成就&#xff0c;建成了全球规模最大、技术领先的5G网络&#xff0c;互联网应用的普及…

vue3 vite title 页面标题设置

效果图&#xff1a; 1. 安装 vite-plugin-html 插件 npm install vite-plugin-html -D2. 修改 vite.config.js import {defineConfig, loadEnv} from vite import { createHtmlPlugin } from "vite-plugin-html" import {resolve} from path import vue from vitej…

我说同事咋找工作命中率这么高,原来是学习了这些招式

最近有两个同事离职了&#xff0c;其中一个还是专科&#xff0c;他俩一个是前端开发&#xff0c;一个是python开发&#xff0c;两个人都接近35岁了。我们还劝告他们&#xff0c;不要离职&#xff0c;要骑驴找马。但了解后&#xff0c;他俩非常有信心的说&#xff1a;不怕&#…

振弦采集仪在岩土工程地质灾害监测中的可行性研究

振弦采集仪在岩土工程地质灾害监测中的可行性研究 引言&#xff1a; 岩土工程地质灾害是指在岩土体中由于自然力和人类活动等因素引起的&#xff0c;对人类生活、财产以及环境造成威胁的灾害。为了及时发现并准确监测地质灾害的发生和演化过程&#xff0c;振弦采集仪作为一种新…

web自动化-下拉框操作/键鼠操作/文件上传

在我们做UI自动化测试的时候&#xff0c;会有一些元素需要特殊操作&#xff0c;比如下拉框操作/键鼠操作/文件上传。 下拉框操作 在我们很多页面里有下拉框的选择&#xff0c;这种元素怎么定位呢&#xff1f;下拉框分为两种类型&#xff1a;我们分别针对这两种元素进行定位和…

6-4 先序输出度为2的结点

作者 DS课程组 单位 临沂大学 本题要求实现一个函数&#xff0c;按照先序遍历的顺序输出给定二叉树中度为2的结点。 函数接口定义&#xff1a; void PreorderPrintNodes( BiTree T);T是二叉树树根指针&#xff0c;PreorderPrintNodes按照先序遍历的顺序输出给定二叉树T中度为…

随笔(二)——项目代码优化

文章目录 前言一、传入的props的默认值定义为空数组1.问题&#xff08;提示对象的类型为unknwn&#xff09;2.优化 二、document 上不存在xxx属性1.问题2.做了一个兼容浏览器的关闭全屏方法3. 解决方法 &#xff08;使用declare globa设置全局变量类型&#xff09;&#xff08;…

ssm球场计费管理系统-计算机毕业设计源码77275

摘 要 大数据时代下&#xff0c;数据呈爆炸式地增长。为了迎合信息化时代的潮流和信息化安全的要求&#xff0c;利用互联网服务于其他行业&#xff0c;促进生产&#xff0c;已经是成为一种势不可挡的趋势。在球馆计费管理的要求下&#xff0c;开发一款整体式结构的球场计费管理…

配置阿里yum源

配置阿里yum源&#xff08;这个很重要&#xff09;&#xff1a;https://developer.aliyun.com/article/1480470 1.备份系统自带yum源配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup2.下载ailiyun的yum源配置文件 2.1 CentOS7 wge…

专业软件测试机构CMA、CNAS资质与测试报告介绍

软件测试机构 一、专业软件测试机构CMA和CNAS的资质介绍如下&#xff1a; 1.CMA&#xff08;China Inspection Body and Laboratory Mandatory Approval&#xff09;是中国计量认证的缩写&#xff0c;是由中国计量认证机构对软件测试实验室在测试技术能力、测试设备、质量保证…

【Java面试】四、MySQL篇(上)

文章目录 1、定位慢查询2、慢查询的原因分析3、索引3.1 数据结构选用&#xff1a;二叉树 & 红黑树3.2 数据结构选用&#xff1a;B树 4、聚簇索引、非聚簇索引、回表查询4.1 聚簇索引、非聚簇索引4.2 回表查询 5、覆盖索引、超大分页优化5.1 覆盖索引5.2 超大分页处理 6、索…

Stable Diffusion AI绘画:从提示词到模型出图的全景指南

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…