拖拽组件 react-dnd 的使用方法

7,599 阅读3分钟

介绍

React DnD 是一组 React 高阶组件,使用的时候只需要使用对应的 API 将目标组件进行包裹,即可实现拖动或接受拖动元素的功能。

DragSource

DragSource 用于包裹需要拖动的组件,使其可以拖动

使用方式

import { DragSource } from 'react-dnd'

const spec = {
    
	beginDrag(props, monitor, component) {
		return props;
	}

	endDrag(props, monitor, component) {
	    return props;
			...
	}

	canDrag(props, monitor) {
			...
	}

	isDragging(props, monitor) {
			...
	}
}

const collect = (connect, monitor) => ({
	// 这里返回一个对象,会将对象的属性都注入到到组件的 props 中去。这些属性需要自己定义。
	connectDropTarget: connect.dropTarget(),
	connectDragPreview: connect.dragPreview,
	isDragging: monitor.isDRagging
})

class MyComponent {
  /* ... */
}

export default DragSource(type, spec, collect)(MyComponent)

参数详解

  • type: 拖拽类型,接收拖拽元素的type一致时才可接收拖拽。type的类型可以是 string,symbol,也可以是用一个函数来返回该组件的其他 props, 必填。
  • spec:拖拽事件的方法对象, 拖动源如何对拖放事件做出反应, 必填。
  • collect:把拖拽过程中需要的信息注入组件的 props,接收两个参数 connect 和 monitor,必填。
spec 对象中的方法

props, monitor, component三个参数可以根据需求选择使用:

  • beginDrag(props, monitor, component): 拖动开始时触发的事件,必须。

  • endDrag(props, monitor, component): 拖动结束时触发的事件,可选。

  • canDrag(props, monitor): 当前是否可以拖拽的事件,可选。

  • isDragging(props, monitor):拖拽时触发的事件,可选。

collect

收集功能函数,包含 connect 和 monitor 参数。 collect函数将返回一个对象,这个对象会注入到组件的 props 中,可以通过 this.props 获取collect返回的所有属性。

  • connect:内置了两个方法,dragSource() 和 dragPreview()。
  1. dragSource()返回一个方法,将source组件传入这个方法,可以将 source DOM 和 React DnD backend 连接起来;
  2. dragPreview() 返回一个方法,你可以传入节点,作为拖拽预览时的角色。
  • monitor: 用于查询当前的拖拽状态,常用的方法
方法 含义
canDrag() 定义是否可以被拖拽,返回true则可以被拖拽
isDragging() 是否正在被拖拽,返回true标识正在被拖拽
getItemType() 返回拖拽组件type
getItem() 返回当前拖动的对象,必须在beginDrag()中返回一个对象指定,否则返回null
getDropResult() 返回接收拖动的对象,必须在DropTarget中的drop()中返回一个对象指定,否则返回null
didDrop() 在 endDrag() 中使用它来测试任何放置目标是否已处理掉落

DropTarget

DropTarget 用于包裹接受拖动对象的组件,使其做出相应反应

import { DropTarget } from 'react-dnd'

const spec = {
	drop(props, monitor, component) {
	    // 返回接受拖拽元素id
		return { id: props.id };
	}

	hover(props, monitor, component) {
	    return props;
			...
	}

	canDrop(props, monitor) {
			...
	}
}

const collect = (connect, monitor) => ({
	connectDropTarget: connect.dropTarget()
})

class MyComponent {
  /* ... */
}

export default DropTarget(types, spec, collect)(MyComponent)
spec 对象中的方法

props, monitor, component三个参数可以根据需求选择使用:

  • drop(props, monitor, component): 组件放下时触发的事件,可选。可以返回 undefined 或普通对象。如果返回一个对象,它将成为放置结果,可以使用 monitor.getDropResult() 获取到。

  • hover(props, monitor, component): 组件在DropTarget上方时响应的事件,可选。

  • canDrop(props, monitor): 使用它来指定是否能够接受该拖拽对象,可选。

collect
  • connect:内置的方法 dropTarget() 对应 dragSource(),返回可以将 drop target 和 React DnD backend 连接起来的方法。
  • monitor:用于查询当前的拖拽状态,常用方法
方法 含义
canDrop() 定义是否可以接受拖拽对象,返回true则可以放置
isOver(options) source是否在hover 在 target上
getItemType() 返回拖拽组件type
getItem() 返回当前拖动的对象,必须在beginDrag()中返回一个对象指定,否则返回null
getDropResult() 返回接收拖动的对象,必须在DropTarget中的drop()中返回一个对象指定,否则返回null
didDrop() 在 endDrag() 中使用它来测试任何放置目标是否已处理掉落

DndProvider

使用 DndProvider 包装应用程序的根组件以启用 React DnD。

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

export default class YourApp {
  render() {
    return (
      <DndProvider backend={HTML5Backend}>
        /* Your Drag-and-Drop Application */
      </DndProvider>
    )
  }
}
  • backend:React DnD 后端,除非自己正在编写自定义的,否则建议使用 React DnD 附带的 HTML5Backend,必填。