aromameng / react-app

0 stars 0 forks source link

react-dnd 使用记录 #1

Open aromameng opened 6 years ago

aromameng commented 6 years ago

官方文档 http://react-dnd.github.io/react-dnd/docs-overview.html 官方案列 http://react-dnd.github.io/react-dnd/examples-chessboard-tutorial-app.html

下面是官方的一个小demo,记录下基本的用法

import React, { Component } from 'react';
import { DragDropContext, DragSource, DropTarget } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import './index.less'

const boxSource = {
    beginDrag(props) {
        return {
            name: props.name,
        }
    },
    endDrag(props, monitor) {
        const item = monitor.getItem()
        const dropResult = monitor.getDropResult()

        if (dropResult) {
            alert(`You dropped ${item.name} into ${dropResult.name}!`)
        }
    },
}

// 定义DragSource
@DragSource('box', boxSource, (connect, monitor) => ({
    connectDragSource: connect.dragSource(),
    isDragging: monitor.isDragging(),
}))
class Box extends Component {
    render() {
        const { isDragging, connectDragSource } = this.props
        const { name } = this.props
        const opacity = isDragging ? 0.4 : 1

        return (
            connectDragSource &&
            connectDragSource(<div className="box" style={{ opacity }}>{name}</div>)
        )
    }
}

const boxTarget = {
    drop() {
        return { name: 'Dustbin' }
    },
}

// 定义DropTarget
@DropTarget('box', boxTarget, (connect, monitor) => ({
    connectDropTarget: connect.dropTarget(),
    isOver: monitor.isOver(),
    canDrop: monitor.canDrop(),
}))
class Dustbin extends Component{
    render() {
        const { canDrop, isOver, connectDropTarget } = this.props
        const isActive = canDrop && isOver

        let backgroundColor = '#ff0'
        if (isActive) {
            backgroundColor = 'darkgreen'
        } else if (canDrop) {
            backgroundColor = '#ccc'
        }

        return (
            connectDropTarget &&
            connectDropTarget(
                <div className="dust" style={{ backgroundColor }}>
                    {isActive ? 'Release to drop' : 'Drag a box here'}
                </div>,
            )
        )
    }
}

class Index extends Component{
    render() {
        return <div>
            <Dustbin />
            <Box name="Glass" />
            <Box name="Banana" />
            <Box name="Paper" />
        </div>
    }
};

export default DragDropContext(HTML5Backend)(Index)
aromameng commented 6 years ago

主要的几个API

monitor 提供的一些方法

// DragSourceMonitor
monitor.canDrag()        // 是否能被拖拽
monitor.isDragging()      // 是否正在拖拽
monitor.getItemType()     // 拖拽组件type
monitor.getItem()         // 当前拖拽的item
monitor.getDropResult()   // 查询drop结果
monitor.didDrop()         // source是否已经drop在target
monitor.getInitialClientOffset()   // 拖拽组件初始拖拽时offset
monitor.getInitialSourceClientOffset()
monitor.getClientOffset() // 拖拽组件当前offset
monitor.getDifferenceFromInitialOffset() // 当前拖拽offset和初始拖拽offset的差别
monitor.getSourceClientOffset()

// DropTargetMonitor
monitor.canDrop()         // 是否可被放置
monitor.isOver(options)   // source是否在target上方
monitor.getItemType()     // 拖拽组件type
monitor.getItem()         // 当前拖拽的item
monitor.getDropResult()   // 查询drop结果
monitor.didDrop()         // source是否已经drop在target
monitor.getInitialClientOffset()   // 拖拽组件初始拖拽时offset
monitor.getInitialSourceClientOffset()
monitor.getClientOffset() // 拖拽组件当前offset
monitor.getDifferenceFromInitialOffset() // 当前拖拽offset和初始拖拽offset的差别
monitor.getSourceClientOffset()