react-dnd 拖拽

介绍

React DnD 是一组 React 高阶组件,可以用来帮你构建复杂的拖拽接口,同时解耦你的组件。React DnD 非常适合像 Trello 和 Storify 这样的应用,在不同地方通过拖拽转移数据,而组件会改变它们的外观和应用的状态来响应拖拽事件。

基本用法

  1. 把应用的根组件包装在 DragDropContext 中
  2. 把可以拖拽的组件包装在 DragSource 中
    1. 设置 type
    2. 设置 spec,让组件可以响应拖拽事件
    3. 设置 collect,把拖拽过程中需要信息注入组件的 props
  3. 把可以接受拖拽的组件包装在 DropTarget 中
    1. 设置 type
    2. 设置 spec,让组件可以响应拖拽事件
    3. 设置 collect,把拖拽过程中需要信息注入组件的 props

翻译成代码就是:

// 1
import HTML5Backend from ‘react-dnd-html5-backend‘;
import { DragDropContext } from ‘react-dnd‘;

class App { ... }
export default DragDropContext(HTML5Backend)(App);

/*---------------------------*/

// 2
import { DragSource } from ‘react-dnd‘;

class MyComponent { ... }
export default DragSource(type, spec, collect)(MyComponent);

/*---------------------------*/

// 3
import { DropTarget } from ‘react-dnd‘;

class MyComponent2 { ... }
export default DropTarget(types, spec, collect)(MyComponent2);

这样,MyComponent 就变得可以拖拽,而 MyComponent2 就变得可以接受拖拽了,但这并不代表 MyComponent 可以放到 MyComponent2 中!

一些概念

React DnD 中有一些特殊的概念,理解这些概念之后才能活用这个库!

  • Backend 实现 DnD 的方式,默认是用 HTML5 DnD API,它不能在触屏环境下工作,而且在 IE 下可定制性比其他浏览器弱。你也可以用自己实现,具体请看官方文档。
  • Items 拖拽数据的表现形式,用 Object 来表示。譬如,要拖拽一张卡片,那这张卡片的数据的表现形式可能是 { id: xxx, content: yyy }
  • Types 表示拖/放组件的兼容性,DragSource 和 DropTarget 必须指定 type。只有在 type 相同的情况下,DragSource才能放到 DropTarget 中。
  • Monitors 用来响应拖拽事件,可以用来更新组件的的状态。
  • Connectors 底层接触 DOM 的东西,用来封装你的组件,让你的组件有拖拽的特性。一般在 collect 方法中指定,然后注入到组件的 props 中,最后 render 方法中包装你自己的组件。
  • DragSource && DropTarget 把上面的概念都绑在一起的东西,也是真正跟你的组件打交道的东西。

主要 API 介绍

这些主要 API 都是通过包装你的组件,然后返回一个新的组件。

DragDropContext(backend)

  • backend 实现 DnD 的方式,一般是 HTML5Backend
export default DragDropContext(HTML5Backend)(App);

DragSource(type, spec, collect)

DropTarget(type, spec, collect)

  • type 必须。type 是自定义的,可以是 string,symbol,也可以是用一个函数来返回该组件的其他 props。该组件只能放到相同 type 的 DropTarget 中。
  • spec 必须。一个带有特定方法的纯 Object,里面是一些响应拖拽事件的方法。
  • collect 必须。一个函数返回一个 Object,这个 Object 会注入到组件的 props 中。
  • options 可选。除非有性能问题,否则不需要关心这个参数。
const type = ‘xxx‘;
const spec = { ... };
function collect(connect, monitor) { ... }

export default DragSource(type, spec, collect)(MyComponent);
export default DropTarget(type, spec, collect)(MyComponent2);

DragSource#spec

让你的组件响应 dnd 相关事件,支持以下方法:

  • beginDrag(props, monitor, component) 必须
  • endDrag(props, monitor, component) 可选
  • canDrag(props, monitor) 可选
  • isDragging(props, monitor) 可选

参数含义如下:

  • props 组件当前的 props
  • monitor 是一个 DragSourceMonitor 实例,用来查询当前 drag state 的信息。
  • component 表示当前组件,可以省略。
const spec = {
    beginDrag(props) {
        return {
            id: props.id,
            content: props.content
        }
    }
    //...
}

DropTarget#spec

让你的组件响应 dnd 相关事件,支持以下方法:

  • drop(props, monitor, component) 可选,响应 drop 事件
  • hover(props, monitor, component) 可选
  • canDrop(props, monitor) 可选

参数含义如下:

  • props 组件当前的 props
  • monitor 是一个 DropTargetMonitor 实例,用来查询当前 drag state 的信息。
  • component 表示当前组件,可以省略。
const spec = {
    drop(props, monitor, component) {
        // 获取正在拖放的数据
        const item = monitor.getItem();
        // 更新组件状态
        component.setState({
            item
        })

    }
}

DragSource#collect(connect, monitor)

DropTarget#collect(connect, monitor)

返回一个 object,这个 object 可以会注入到组件的 props 中。

  • connect 一个 DragSourceConnector/DropTargetConnector 实例,可以用connect.dragSource()/connect.dropTarget() 来封装我们的组件。
  • monitor 一个 DragSourceMonitor/DropTargetMonitor 实例,用来查询当前拖拽的信息。
function collect(connect, monitor) {
    return {
        isDragging: monitor.isDragging(),
        connectDragSource: connect.dragSource()
    }
}

class MyComponent extends Component {
    render() {
        // 可以访问 collect 中返回的  object
        const { isDragging, connectDragSource } = this.props;
        // 需要用 connect.dragSource()/connect.dropTarget() 封装自己的组件
        return connectDragSource(
            <div>123</div>
        )
    }
}

具体例子

出处

参考资料

时间: 2024-10-28 11:08:25

react-dnd 拖拽的相关文章

react实现拖拽

import React from 'react' export default class extends React.Component { constructor(props) { super(props); this.state = { translateX: 0, translateY: 0, }; } small_down=(e)=> { var obig = this.refs.move.parentNode; var osmall = this.refs.move; var e

React.js实现原生js拖拽效果及思考

一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖拽效果. 首先,其实拖拽效果的思路是很简单的.主要就是三个步骤: 1.onmousedown的时候,启动可拖拽事件,记录被拖拽元素的原始坐标参数. 2.onmousemove的时候,实时记录鼠标移动的距离,结合被拖拽元素第一阶段的坐标参数,计算并设置新的坐标值. 3.onmouseup的时候,关闭可拖拽事件

再谈React.js实现原生js拖拽效果

前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目地就是要尽量避免直接操作dom元素,所以我们在对dom元素进行操作的时候需要注意,我之前为了获取form的参数就直接用了var dragBox=document.getElementById('form')去找dom,但是其实记录from的初始位置,可以在其子组件更新父组件参数的时候调用.即在MyF

react 拖拽排序

react 拖拽排序.项目中用到了,记一笔.没有用react-dnd, 没有用react-beautiful-dnd, 因为需求简单,所以就自己撸了一个. 代码很简单 定义css, 两个动画 .drag-up { -webkit-animation: dragup ease 0.2s 1; animation: dragup ease 0.2s 1; -webkit-animation-fill-mode: forwards; animation-fill-mode: forwards; bac

Atitit。D&amp;D drag&amp;drop拖拽功能c#.net java swing的对比与实现总结

Atitit.D&D drag&drop拖拽功能c#.net java swing的对比与实现总结 1. 实现一个D&D操作一般包括三个步骤: 1 2. .net黑头的拖曳机制.必须有DragEnter事件(单独写DragDrop事件是不会具有拖拽功能的) 2 3. ---java黑头的拖曳..必须有DragEnter事件(单独写 Drop事件是不会具有拖拽功能的) 2 4. 代码 3 5. 参考 5 1. 实现一个D&D操作一般包括三个步骤: 首先实现一个拖拽源,这个拖拽

[Java]接受拖拽文件的窗口

至于这个问题,Java的awt.dnd包下提供了许多完成这一功能的类 例如DropTarget.DropTargetListener等 先来讲一下DropTarget类,这个类完成和拖拽.复制文件等操作和Component的关联 常用的构造方法有这些: DropTarget(Component c, DropTargetListener dtl) c:要与它关联的组件 dtl:执行事件处理的DropTargetListener DropTarget(Component c, int ops, D

VM虚拟机无法拖拽、粘贴、复制

VM无法从客户机拖放/复制文件到虚拟机的解决办法: 将这两项取消勾选,点击[确定].再次打开,勾选,点击[确定] 原因分析:可能是VM中默认是不支持该功能的,但是在配置窗体上确实默认打钩打上的. 依据:在操作过程中,你可以查看该虚拟机的的配置文件(*.vmx).观察以下节点 isolation.tools.copy.disable = "FALSE" isolation.tools.dnd.disable = "FALSE" isolation.tools.past

原生拖拽,拖放事件(drag and drop)

原生拖拽,拖放事件(drag and drop) 拖拽,拖放事件可以通过拖拽实现数据传递,达到良好的交互效果,如:从操作系统拖拽文件实现文件选择,拖拽实现元素布局的修改. drag and drop事件流程 一个完整的drag and drop流程通常包含以下几个步骤: 设置可拖拽目标.设置属性draggable="true"实现元素的可拖拽. 监听dragstart设置拖拽数据 为拖拽操作设置反馈图标(可选) 设置允许的拖放效果,如copy,move,link 设置拖放目标,默认情况

React-Native ListView拖拽交换Item

在高仿"掘金"客户端的那个项目中,你会发现在打开和关闭"首页展示标签"中,我并没有实现可拖拽换位item的效果.不过在自己新写的Gank.io项目中,将这一功能实现了一把,在此记录一下.先上效果图 对,就是这样- 在实现这个效果前,我的思路是这样的,布局->item可点击突出显示->可移动item->可交换item->抬起手指恢复正确的位置.下面一一解释. 布局 忘了说了,由于这个界面的item的元素较少,并且为了方便起见,我并没有采用Lis