专栏名称: 前端从进阶到入院
我是 ssh,只想用最简单的方式把原理讲明白。wx:sshsunlight,分享前端的前沿趋势和一些有趣的事情。
目录
相关文章推荐
江南都市报  ·  亚冠:泽卡、克雷桑传射&卡扎破门,泰山3比1 ... ·  9 小时前  
江南都市报  ·  亚冠:泽卡、克雷桑传射&卡扎破门,泰山3比1 ... ·  9 小时前  
现代快报  ·  北京国安一球员家人称其国外集训因伤脑死亡 ·  9 小时前  
现代快报  ·  北京国安一球员家人称其国外集训因伤脑死亡 ·  9 小时前  
51好读  ›  专栏  ›  前端从进阶到入院

这个17k star的拖拽库有点料

前端从进阶到入院  · 公众号  ·  · 2024-05-23 22:42

正文

一、背景

近期在工作中遇到了一个新的需求,该需求需要实现某个组件的拖拽,面对这个需求的第一个项目肯定是问问度娘和用最大同性交友网站进行搜索,最终皇天不负有心人,让我找到了这个17k star的React拖拽库——React DnD。

image.png

二、简单使用

2.1 安装

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

2.2 三个核心点

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

  1. DndProvider组件
  2. useDrag函数
  3. useDrop函数

2.2.1 DndProvider组件

如果想让某一内容使用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;

2.2.2 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());
        },
        // 指定当前是否允许拖动,默认允许
        canDragmonitor => {
            return true;
        },
        // 监听功能
        collect(monitor, props) => {
            return {
                isDragging: monitor.isDragging()
            };
        }
    });
    return (
        <div ref={drag}>
            {children}
        div>

    );
};

export default SourceBox;

2.2.3 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('我已经被放到目标!!!')
        },
        // 监听功能
        collectmonitor => {
            return {
                // 是否重叠
                isOver: monitor.isOver(),
                // 是否可以放置
                canDrop






请到「今天看啥」查看全文