React-DnD 的使用

前端之家收集整理的这篇文章主要介绍了React-DnD 的使用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

介绍

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

基本用法

@H_403_6@
  • 把应用的根组件包装在 DragDropContext

  • 把可以拖拽的组件包装在 DragSource

    @H_403_6@
  • 设置 type

  • 设置 spec,让组件可以响应拖拽事件

  • 设置 collect,把拖拽过程中需要信息注入组件的 props

  • 把可以接受拖拽的组件包装在 DropTarget

    @H_403_6@
  • 设置 type

  • 设置 spec,让组件可以响应拖拽事件

  • 设置 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,collect)(MyComponent2);

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

    一些概念

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

    • Backend 实现 DnD 的方式,默认是用 HTML5 DnD API,它不能在触屏环境下工作,而且在 IE 下可定制性比其他浏览器弱。你也可以用自己实现,具体请看官方文档。

    • Items 拖拽数据的表现形式,用 Object 来表示。譬如,要拖拽一张卡片,那这张卡片的数据的表现形式可能是 { id: xxx,content: yyy }

    • Types 表示拖/放组件的兼容性,DragSourceDropTarget 必须指定 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,collect)

    DropTarget(type,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,collect)(MyComponent);
    export default DropTarget(type,collect)(MyComponent2);

    DragSource#spec

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

    • beginDrag(props,monitor,component) 必须

    • endDrag(props,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,component) 可选,响应 drop 事件

    • hover(props,component) 可选

    • canDrop(props,monitor) 可选

    参数含义如下:

    • props 组件当前的 props

    • monitor 是一个 DropTargetMonitor 实例,用来查询当前 drag state 的信息。

    • component 表示当前组件,可以省略。

    const spec = {
        drop(props,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>
            )
        }
    }

    具体例子

    出处

    参考资料

    猜你在找的React相关文章