锐客网

react拖曳组件react-dnd的简单封装使用

分享原因 由于项目中需要使用拖曳组件(需求:全局,跨组件,跨数据),我选择了react-dnd
概念 React DnD 是一组 React 高阶组件,我们在使用的时候只需要将目标元素进行包裹,就可以实现目标元素具有拖动或接受拖动的功能。它将整个拖动的事件完整的描述了出来,这使得我们在使用的过程变得简单易用和扩展上有了无限的可能,在处理复杂拖曳和丰富需求的时候强烈建议使用它。
官网 https://react-dnd.github.io/r...
基本

  • 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'; ....

    组件参数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 ({option.content}); }; 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 ({option.content}); }; //同一list之间拖动 export const dragList = ( list: Array, 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, targetList: Array, 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) { {}} content={ { console.log(source, target, '回调'); if (target) { this.handleDrag( source.data.sort, target.data.sort, ); } }} /> } styleType="border" />}

    【react拖曳组件react-dnd的简单封装使用】react拖曳组件react-dnd的简单封装使用
    文章图片


    渲染