react拖曳组件react-dnd的简单封装使用
2021/11/27 8:10:03
本文主要是介绍react拖曳组件react-dnd的简单封装使用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
分享原因
由于项目中需要使用拖曳组件(需求:全局,跨组件,跨数据),我选择了react-dnd
概念
React DnD 是一组 React 高阶组件,我们在使用的时候只需要将目标元素进行包裹,就可以实现目标元素具有拖动或接受拖动的功能。它将整个拖动的事件完整的描述了出来,这使得我们在使用的过程变得简单易用和扩展上有了无限的可能,在处理复杂拖曳和丰富需求的时候强烈建议使用它。
官网 https://react-dnd.github.io/react-dnd/
基本
- Item type:跟redux或其他组件一样,item用来描述拖动dom的数据对象,type用来标识一组可拖动和接收
- Backend:用来表现dom拖动现象,我使用了HTML5Backend
- Monitors:用来查询当前拖动状态(数据,dom,位置等),强大的收集功能
- Connectors:用于Backend和组件状态之间的连接
- hook:useDrag 将组件作为可拖动的来源注册到dnd useDrop 将组件作为可接收拖动来源注册到dnd
使用方法
导入npm install react-dnd react-dnd-html5-backend
初始化
import { HTML5Backend } from 'react-dnd-html5-backend'; <DndProvider backend={HTML5Backend}> .... </>
组件参数type.ts
export type DragProps = { name: string; //名称标记 type: string; //暂用于标记拖拽类型,接收者和发送者一致 role: string; // data: any; //绑定的数据用于拖曳后操作数据 content: JSX.Element; //绑定的元素 onDragFinished: Function; //拖动结束回调. }; export type AcceptorProps = { name: string; //名称标记 type: string; //暂用于标记拖拽类型,接收者和发送者一致 role: string; // data: any; //绑定的数据用于拖曳后操作数据 content: JSX.Element; //绑定的元素 styleType: 'background' | 'border'; // customStyle:{ // canDrop:string, // isActive:string // } onHover: Function; //移入区域. };
组件MyDrag.ts
import { useDrag, useDrop } from 'react-dnd'; import { DragProps, AcceptorProps } from './type'; export const Dragger = function Dragger(option: DragProps) { const { name, data, type, onDragFinished } = option; const [{ isDragging }, drag] = useDrag(() => ({ type: type, item: { name: name, data: data }, end: (item, monitor, ...arg) => { console.log(arg); const dropResult = monitor.getDropResult(); if (item && dropResult) { console.log('source:', item); console.log('target:', dropResult); } if (onDragFinished) { onDragFinished(item, dropResult); } }, collect: (monitor) => ({ isDragging: monitor.isDragging(), handlerId: monitor.getHandlerId(), }), })); const opacity = isDragging ? 0.4 : 1; return ( <div ref={drag} role={option.role} style={{ opacity }} data-id={`${option.name}`} > {option.content} </div> ); }; export const Acceptor = (option: AcceptorProps) => { const { name, data, type, styleType, onHover } = option; const [{ canDrop, isOver }, drop] = useDrop(() => ({ accept: type, drop: () => option, hover: () => { if (onHover) { onHover(); } }, collect: (monitor) => ({ isOver: monitor.isOver(), canDrop: monitor.canDrop(), }), })); const isActive = canDrop && isOver; let backgroundColor = '#222'; let borderBottom = '0px solid rgba(31, 92, 206, 0)'; if (isActive) { backgroundColor = 'rgba(64, 224, 208, 0.3)'; borderBottom = '1px solid #26BD11'; } else if (canDrop) { backgroundColor = 'rgba(100, 149, 277, 0.3)'; borderBottom = '1px solid #2063AF'; } return ( <div ref={drop} role={'Acceptor'} style={ styleType === 'background' ? { backgroundColor } : { borderBottom } } > {option.content} </div> ); }; //同一list之间拖动 export const dragList = ( list: Array<any>, crtIndex: number, willIndex: number, ) => { let targetItem = list[crtIndex]; let delIndex = crtIndex < willIndex ? crtIndex : crtIndex + 1; list.splice(willIndex, 0, targetItem); list.splice(delIndex, 1); return list; }; //来自不同list之间拖动,1.删除原来 2不删除原来 export const dragToList = ( list: Array<any>, targetList: Array<any>, crtIndex: number, willIndex: number, del: 1 | 2, ) => { let targetItem = list[crtIndex]; targetList.splice(willIndex, 0, targetItem); if (del === 1) { list.splice(crtIndex, 1); } return { list, targetList }; };
具体使用
import { Dragger, Acceptor, dragList } from '@/components/Drag'; //同列表之间拖曳 handleDrag(crt: number, target: number) { conslog.log(dragList(newPanels, crt, target);) } renderDrag(item: ItemProps, children) { <Acceptor key={item.type} name={item.title} data={item} type="xxx" role="xxxAccept" onHover={() => {}} content={ <Dragger name={item.title} data={item} type="xxx" role="xxxDrag" content={children} onDragFinished={(source: any, target: any) => { console.log(source, target, '回调'); if (target) { this.handleDrag( source.data.sort, target.data.sort, ); } }} /> } styleType="border" /> }
这篇关于react拖曳组件react-dnd的简单封装使用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-19Vue3入门教程:从零开始搭建你的第一个Vue3项目
- 2024-11-19vue2 开发移动端h5 使用那个ui框架比较好?-icode9专业技术文章分享
- 2024-11-19ReactJS结合TypeScript、Vite、Redux和TanStack (React Query) 实战教程
- 2024-11-19Vue3资料入门教程:零基础快速上手指南
- 2024-11-19Vue3资料:新手入门教程与实战指南
- 2024-11-19Vue资料:新手入门vue.js教程与实践指南
- 2024-11-19Vue资料:初学者入门指南
- 2024-11-18tcpdf可以等待vue动态页面加载完成后再生成pdf吗?-icode9专业技术文章分享
- 2024-11-16Vue3资料:新手入门必读教程
- 2024-11-16Vue3资料:新手入门全面指南