react-dnd实现拖拽效果

最终效果

拖拽.gif

几个概念

  • DragSource 用于包装你需要拖动的组件,使组件能够被拖拽(make it draggable)
  • DropTarget 用于包装接收拖拽元素的组件,使组件能够放置(dropped on it)
  • DragDropContext 用于包装拖拽根组件,DragSource 和 DropTarget 都需要包裹在DragDropContext内

参数说明

 DragSource(type, spec, collect)
 DropTarget (type, spec, collect)
  • DragSource和DropTarget各有三个参数

type: 拖拽类型,必填。当 source组件的type 和 target组件的type 一致时,target组件可以接受source组件。
spec: 拖拽事件的方法对象,必填。
collect: 把拖拽过程中需要信息注入组件的 props,接收两个参数 connect and monitor,必填。

具体实现步骤

  1. 引入文件
import HTML5Backend from 'react-dnd-html5-backend';
import { DragDropContext, DragSource, DropTarget } from 'react-dnd';
  1. 拖拽源组件

拖拽源组件html

<template name="AxisSourceItem">
  <div class="{styles.btnWrap}"><ant-Button type="primary" size="small" disabled="{disabled}">{data.name}<ant-Icon type="plus" /></ant-Button></div>
</template>

拖拽源组件js

// 设置分析指标弹层:拖拽源
const axisListSource = {
  beginDrag(props) {
    return {
      data: props.data,
    };
  }
};

@registerTmpl('AxisSourceItem')
@DragSource(props => props.type, axisListSource, (connect, monitor) => ({
  connectDragSource: connect.dragSource(),
  isDragging: monitor.isDragging(),
}))
@inject('store')
@observer
class AxisSourceItem extends Component {
  render() {
    const { connectDragSource } = this.props;

    return connectDragSource(tmpls.AxisSourceItem(this.props, {
      styles,
      disabled: this.props.data.status === 1 ? false : true,
    }));
  }
}
  1. 拖拽目标组件

拖拽目标组件html

<template name="AxisXTargetArea">
  <span class="{styles.targetArea}">
    <#if {data.name}>
      <ant-Button type="primary" size="small">{data.name}</ant-Button><ant-Icon type="minus" onClick="{deleteXData}"/>
    </#if>
  </span>
</template>

拖拽目标组件js

// 拖拽到的目标组件
const chooseListTarget = {
  drop(props, monitor) {
    props.onDrop(monitor.getItem());
  }
};

// 设置分析指标弹层:拖拽x轴接受区域组件
@registerTmpl('AxisXTargetArea')
@DropTarget(props => props.accepts, chooseListTarget, (connect, monitor) => ({
  connectDropTarget: connect.dropTarget(),
  isOver: monitor.isOver(),
  canDrop: monitor.canDrop(),
}))
@inject('store')
@observer
class AxisXTargetArea extends Component {
  constructor() {
    super();
  }

  // 删除x轴选中内容
  @autobind
  deleteXData() {
    this.props.delXData();
  }

  render() {
    const { connectDropTarget } = this.props;

    return connectDropTarget(tmpls.AxisXTargetArea(this.state, this.props, this, {
      styles,
    }));
  }
}
  1. 拖拽组件在根组件中的使用

使用DragDropContext包裹根组件
拖拽结束后交互处理

  • html
...
<AxisSourceItem type="bandsDragDrop" data="{this}"/>
...
<AxisXTargetArea accepts="bandsDragDrop" onDrop="{'bandChartX' | onDrop}" data="{dragBandChartX}" delXData="{delXData}"/>
...
  • js
@registerTmpl("BandDiagnostic")
@inject("store")
@DragDropContext(HTML5Backend) // 将根组件用拖拽组件包起来
@observer
class BandDiagnostic extends Component {
  ...
  //拖动结束后的操作
  onDrop(index) {
    return (item) => {
      if (index === 'bandChartX') {
        this.setState({
          dragBandChartX: {
            id: item.data.code,
            name: item.data.name,
          }
        });
      } else if (index === 'bandChartY') {
        this.setState({
          dragBandChartY: {
            id: item.data.code,
            name: item.data.name,
          }
        });
      }
    };
  }
  ...
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,944评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,644评论 18 139
  • 孤蝉独鸣翘北松,沉香不在瘦花丛。 小楼烛火掩垂帘,独上穹庐对月空。 风华自饮不知忆,瑶轸千绪思不同。 芳笺几许解花...
    清远尘阅读 652评论 88 33
  • du du du
    五月清晨的文明少年阅读 880评论 0 0