react-dnd拖拽库的使用

一、简单使用

安装

npm install react-dnd -S // react-dnd包,其核心包
npm install react-dnd-html5-backend -S // 拖拽的底层实现所需要的库

通过使用React DnD这个库,我认为里面最有用的部分包含一个组件和两个Hook API,它们分别是:

  • DndProvider组件
  • useDrag函数
  • useDrop函数

如果想让某一内容使用React DnD的能力,需要将该部分用DndProvider进行包裹,其接收参数如下所示:

  • backend:必填。一个React DnD后端。目前官方文档有三个,分别为:react-dnd-html5-backend、- react-dnd-touch-backend、react-dnd-test-backend,但是常用的还是react-dnd-html5-backend。
  • context:可选的。用于配置后端的后端上下文。这取决于后端实现。
  • options:可选的。用于配置后端的选项对象。这取决于后端实现。

下面来一起看看该组件的简单使用:

import {DndProvider} from 'react-dnd';
import {HTML5Backend} from 'react-dnd-html5-backend';

function App() {
  return (
    <div className="App">
      <DndProvider backend={HTML5Backend}>
        此处将放拖拽相关内容
      </DndProvider>
    </div>
  );
}

export default App;

useDrag函数
既然知道了整个操纵空间,接下来需要了解的就是从什么位置进行拖拽,该库提供了useDrag hook API,该元素可以让一个DOM元素实现拖拽效果。

  1. 参数
    (1) spec:创建规范对象的规范对象或函数,其详细内容如下所示:

1)type

必须,是一个字符串或Symbol,只有drop和此值相同才可以进行放置;

2)item

必须,用于描述被拖动的数据

3)previewOptions

可选的,一个简单对象,用于描述拖动预览选项;

4)options

可选的,一个简单对象

5)end(item, monitor)

可选的,当拖拽停止,该函数被调用;

6)canDrag(monitor)

可选的,使用它指定当前是否允许拖动;

7)isDragging(monitor)

可选的,默认情况下,只有启动拖动操作的拖动源才被视为拖动;

8)collect

可选的,监听功能

  1. 返回值
    返回值是一个数组,数组内容分别为:

collected:一个对象,包含从collect函数收集的属性,如果collect未定义函数,则返回一个空对象;drag:拖动器的连接器功能,必须附加到DOM的可拖动部分;dragPreview:用于拖动预览的连接器功能,可以附加到DOM的预览部分;

  1. 与拖动部分建立连接
    通过ref属性,将drag或dragPreview绑定到拖拽源上。

下面一起来看看useDrag部分的使用

import {useDrag} from 'react-dnd';

const SourceBox = props => {
    const {children} = props;

    /**
     * 返回的参数
     * collected:一个对象,包含从collect函数收集的属性,如果collect未定义函数,则返回一个空对象
     * drag:拖动器的连接器功能,必须附加到DOM的可拖动部分
     * dragPreview:用于拖动预览的连接器功能,可以附加到DOM的预览部分
     */
    const [collected, drag, dragPreview] = useDrag({
        // 只有drop和此值相同才可以进行放置
        type: 'box',
        // 描述要拖动的数据
        item: {
            detail: '我是可以拖动的数据!!!'
        },
        // 拖动停止的手end将会被调用
        end: (item, monitor) => {
            // getDropResult()获取释放后的结果
            console.log('monitor.getDropResult():', monitor.getDropResult());
            // source是否已经drop在target
            console.log('monitor.didDrop()', monitor.didDrop());
        },
        // 指定当前是否允许拖动,默认允许
        canDrag: monitor => {
            return true;
        },
        // 监听功能
        collect: (monitor, props) => {
            return {
                isDragging: monitor.isDragging()
            };
        }
    });
    return (
        <div ref={drag}>
            {children}
        </div>
    );
};

export default SourceBox;

useDrop函数
为了将内容放置到目标位置,提供了useDrop函数,如下所示:

  1. 参数
    (1) spec:创建规范对象的规范对象或函数,其详细内容如下所示:

1)accept

必须,一个字符串,此放置目标将仅对于指定类型的拖动源产生的项目作出反应;

2)options

可选的,一个普通的对象;

3)drop(item,monitor)

可选的,当兼容项目放在目标时被调用;

4)hover(item,monitor)

可选的,将项目悬停在组件时调用;

5)canDrop(item,monitor)

可选的,用它来指定放置目标是否接受该拖拽内容;

6)collect

可选的,监听功能

  1. 返回值
    返回值是一个数组,数组内容分别为:

collected:一个对象,包含从collect函数收集的属性,如果collect未定义函数,则返回一个空对象;drop:一个用于放置目标的连接器函数,必须附加到DOM的放置部分;

  1. 与放置部分建立连接
    通过ref属性,将drop与放置部分建立连接。

下面一起来看看useDrop部分的使用

import {useDrop} from "react-dnd";

const TargetBox = () => {
    const [collected, drop] = useDrop({
        //  此放置目标将仅对于指定类型的拖动源产生的项目作出反应
        accept: 'box',
        // 当兼容项目放在目标时调用
        drop: (item, monitor) => {
            console.log('我已经被放到目标!!!')
        },
        // 监听功能
        collect: monitor => {
            return {
                // 是否重叠
                isOver: monitor.isOver(),
                // 是否可以放置
                canDrop: monitor.canDrop(),
                item: monitor.getItem(),
                didDrop: monitor.didDrop()
            };
        }
    });

    return (
        <div ref={drop}>
            <div className="targetBox">
                这是放置的区块
            </div>
        </div>
    );
};

export default TargetBox;

monitor详细内容
useDrag和useDrop上挂载了很多选项,这些选项中很多存在monitor对象,该对象上挂载了很多方法,下面就简要概述几个主要方法,如下所示:

  1. drag上的monitor上的方法
    在这里插入图片描述
  2. drop上的monitor上的方法
    在这里插入图片描述
    学习感悟

end方法的调用时机晚于drop的调用时机,所以只有在end中做释放后的数据处理才能保证系统的正确性,如果在drop中就更新state或React redux中数据,会引发错误;
item数据是从Drag到Drop之间的桥梁,在drag中定义的item数据可以通过monitor.getItem()获取;
drop回调的返回值是从Drop到Drag之间的桥梁,在end中可以通过monitor.getDropResult()其返回值;
一些挂载在monitor上的位置函数并不一定适用于所有的场景,需要引入DOM相关的位置操作。

  • 28
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C+ 安口木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值