首页 > 其他分享 >使用react-dnd实现表格之间互相拖拽

使用react-dnd实现表格之间互相拖拽

时间:2024-02-05 13:33:23浏览次数:30  
标签:dnd const moveRow index dragIndex list react hoverIndex 拖拽

/** 
引用 immutability-helper 轮子中的 update; 意为:在不改变原始来源的情况下改变数据副本
*/
1 import React, { Component } from 'react'; 2 import { DndProvider, useDrag, useDrop } from 'react-dnd'; 3 import HTML5Backend from 'react-dnd-html5-backend'; 4 import { Table } from 'antd'; 5 import { Form } from '@ant-design/compatible'; 6 import update from 'immutability-helper'; 7 8 const EditableContext = React.createContext(); 9 10 export default class AppIndex extends Component { 11 constructor(props) { 12 super(props); 13 this.state = {
       // 表格1 14 list: [{ id: 1, start: '头下标1', end: '333' }, { id: 2, start: '头下标2', end: '354345' }], 15 newList: [// 表格2 16 { id: 12, start: '头部下标1', end: 'tb' }, 17 { id: 112, start: '头部下标2', end: 'yu' }, 18 ], 19 columns: [ // 表格1 20 { 21 title: '头', 22 dataIndex: 'start', 23 }, 24 { 25 title: '尾', 26 dataIndex: 'end', 27 }, 28 ], 29 newColumns: [ // 表格2 30 { 31 title: '头部', 32 dataIndex: 'start', 33 }, 34 { 35 title: '尾否', 36 dataIndex: 'end', 37 }, 38 ], 39 }; 40 } 41 42 componentWillUnmount() { // 处理内存泄漏问题 43 window.onresize = null; 44 this.setState = () => { 45 return 0; 46 }; 47 } 48 49 /**
     环节拖拽
     @params dragIndex:拖拽表格对应id
    */ 50 moveRow = (dragIndex, hoverIndex, dragName, hoverName) => { 51 const { list, newList } = this.state; 52 const { state } = this; 53 if (dragName === 'table2' && dragName !== hoverName) { 54 // 从表2拖 55 this.setState( 56 update(state, { 57 newList: { 58 $splice: [[dragIndex, 1]], 59 }, 60 list: { // hoverIndex为undefined 表示从表2开始拖拽到表1的同时,表1没有数据 61 $splice: 62 hoverIndex === undefined 63 ? [[0, 0, newList[dragIndex]]] 64 : [[hoverIndex, 1, list[hoverIndex]], [hoverIndex, 0, newList[dragIndex]]], 65 }, 66 }) 67 ); 68 } else if (dragName === 'table1' && dragName !== hoverName) { 69 // 从表1拖 70 this.setState( 71 update(state, { 72 list: { 73 $splice: [[dragIndex, 1]], 74 }, 75 newList: { 76 // 从上向下拖拽没问题 第一个数组删,第二个数组增 77 $splice: 78 hoverIndex === undefined 79 ? [[0, 0, list[dragIndex]]] 80 : [[hoverIndex, 1, newList[hoverIndex]], [hoverIndex, 0, list[dragIndex]]], 81 }, 82 }) 83 ); 84 } 85 }; 86 87 render() { 88 const { list, columns, newList, newColumns } = this.state; 89 const typeRow = 'DragbleBodyRow'; 90 const EditableRowDrag = ({ 91 index, 92 moveRow, 93 tableName, 94 form, 95 className, 96 style, 97 ...restProps 98 }) => { 99 const ref = React.useRef(); 100 const [{ isOver, dropClassName }, drop] = useDrop({ // 开始拖拽 101 accept: typeRow, 102 collect: monitor => { 103 const { index: dragIndex } = monitor.getItem() || {}; 104 if (dragIndex === index) { 105 return {}; 106 } 107 return { 108 isOver: monitor.isOver(), 109 dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward', 110 }; 111 }, 112 drop: item => { 113 if (index === undefined) {// 若被放数据的表中没有数据 则index为undefined 114 this.moveRow(item.index, index, item.tableName, tableName); 115 } else { 116 moveRow(item.index, index, item.tableName, tableName); 117 } 118 }, 119 }); 120 const [, drag] = useDrag({ // 准备放下 121 item: { type: typeRow, index, tableName }, 122 collect: monitor => ({ 123 isDragging: monitor.isDragging(), 124 }), 125 }); 126 drop(drag(ref)); 127 return ( 128 <EditableContext.Provider value={form}> 129 <tr 130 ref={ref} 131 className={`${className}${isOver ? dropClassName : ''}`} 132 style={{ cursor: 'move', ...style }} 133 {...restProps} 134 /> 135 </EditableContext.Provider> 136 ); 137 }; 138 const EditableFormRowDrag = Form.create()(EditableRowDrag); 139 const components = { 140 // header: { 141 // cell: ResizeableTitle, 142 // }, 143 body: { 144 row: EditableFormRowDrag, 145 // cell: EditableCell, 146 }, 147 }; 148 149 const NewTable = ( 150 <> 151 <Table 152 components={components} 153 rowKey="id" 154 dataSource={list} 155 columns={columns} 156 pagination={false} 157 onRow={(record, index) => ({ 158 index, 159 moveRow: this.moveRow, 160 tableName: 'table1', // 表格唯一标识 161 })} 162 /> 163 <br /> 164 <Table 165 components={components} 166 rowKey={'id' || Math.random()} 167 dataSource={newList} 168 columns={newColumns} 169 pagination={false} 170 onRow={(record, index) => { 171 return { 172 index, 173 moveRow: this.moveRow, 174 tableName: 'table2', // 表格唯一标识 175 }; 176 }} 177 /> 178 </> 179 ); 180 return <DndProvider backend={HTML5Backend}>{NewTable}</DndProvider>; 181 } 182 }

 

标签:dnd,const,moveRow,index,dragIndex,list,react,hoverIndex,拖拽
From: https://www.cnblogs.com/xiaona-boke/p/18007795

相关文章

  • 迅为RK3588开发板ubuntu和window互传图形界面直接拖拽进行文件传输
    确保以及安装了VMwareTools。如下图所示表示已安装过了。和windows端文件夹间传输一样直接拖拽进去即可,如下图所示:也可拖拽到终端,如下图所示:更多内容可以B站搜索迅为RK3588开发板......
  • Vue 用户提问:如何在 React 中实现全局路由守卫?
    前言如果想在vue中实现全局路由守卫,只需要在beforeEach中写路由守卫逻辑即可。但是如果使用react的话,应该怎么做呢?在react中,其实是没有beforeEach的,如果需要实现路由守卫,需要结合 ReactRoute 路由库,自己手动搓一个路由守卫。需求我的这个管理系统对于路由守卫......
  • Idea Jrebel 报错:Cannot reactivate,offline seat in use
    一、问题描述在使用ideaJrebel续期的时候,修改idea激活服务器地址时,遇到报错:Cannotreactivate,offlineseatinuse.ClickWorkonlineinJRebelconfigurationtoreturnofflineseat...二、问题解决找到idea配置文件:jrebel.properties,修改文件属性:rebel.license.......
  • 尤雨溪说:为什么Vue3 中应该使用 Ref 而不是 Reactive?
    每次有同学学习到 vue3 的时候,总会问:“ref 和 reactive 我们应该用哪个呢?”我告诉他:“我们应该使用 ref,而不是 reactive”。那么此时同学就会有疑惑:“为什么呢?ref 还需要 .value 处理,reactive 看起来会更加简单呢?”嗯....每当这个时候,我都需要进行一次长篇大论来解释......
  • react antd的Table中,如何动态的改变表格数据
    在ReactAntd中,如果您改变了Table组件的数据源(dataSource),Table会自动重新渲染以反映新的数据。因此,只要您在状态或props中正确更新数据源,Table就会自动更新。以下是一个示例代码片段,展示如何使用React状态(state)和按钮来更改数据源并更新Table组件:importReact,{useState}fr......
  • vue中的响应式和react中的响应式一样吗?
    Vue.js和React在实现响应式原理上有所不同:Vue.js的响应式机制:依赖收集(DependentDataCollection):Vue使用了基于getter/setter的Object.defineProperty()方法,对数据对象的属性进行拦截。当一个组件渲染时,Vue能够跟踪到模板中哪些数据被访问(getter),并记录下它们之间的......
  • react 点击按钮 div隐藏显示 添加展开收起动画效果
    js代码const[collapse,setCollapse]=useState(false)  const[showBack,setShowBack]=useState(false)  constchangeCollapse=()=>{//获取展开收起目标元素    constheaderDes=document.querySelector('.phone_header_des');  ......
  • react antd 组件取值的方法
    在React中使用AntDesign(antd)组件,可以通过不同的方式获取组件的值,具体取决于所使用的AntDesign组件和其相关的API。一般来说,大部分AntDesign组件都有value属性或onChange事件,可用于获取或监听组件的值。以下是几个常见的AntDesign组件的取值方法示例:1、Input输入框组件:......
  • react-native中memo、useMemo、useCallback 你真的用明白了吗
    memo的作用在React的渲染流程中,一般来说,父组件的某个状态发生改变,那么父组件会重新渲染,父组件所使用的所有子组件,都会强制渲染。而在某些场景中,子组件并没有使用父组件传入的没有发生更改的状态时,子组件重新渲染是没有必要的。因此有了React.memomemo的使用memo是个高阶......
  • vue3+elementplus+vuedraggable插件,实现左右拖拽移入,和上下拖拽排序
    先看目标效果(gif由迅捷gif工具制作,使用vscode可以打开gif,进行预览)效果分析1.左右区域,支持拖拽。左侧选项,拖入右边。可以新建大模块,也可以给模块新增一项。2.模块内部,支持拖拽排序,并按照排序,生成一个简单的层级。3.模块名字支持编辑。同时增加表单校验,名字不存在,则无法保存。......