最終效果
拖拽.gif
幾個(gè)概念
- DragSource 用于包裝你需要拖動(dòng)的組件,使組件能夠被拖拽(make it draggable)
- DropTarget 用于包裝接收拖拽元素的組件,使組件能夠放置(dropped on it)
- DragDropContext 用于包裝拖拽根組件命贴,DragSource 和 DropTarget 都需要包裹在DragDropContext內(nèi)
參數(shù)說明
DragSource(type, spec, collect)
DropTarget (type, spec, collect)
- DragSource和DropTarget各有三個(gè)參數(shù)
type: 拖拽類型,必填秆吵。當(dāng) source組件的type 和 target組件的type 一致時(shí)样傍,target組件可以接受source組件。
spec: 拖拽事件的方法對象镜遣,必填己肮。
collect: 把拖拽過程中需要信息注入組件的 props,接收兩個(gè)參數(shù) connect and monitor悲关,必填谎僻。
具體實(shí)現(xiàn)步驟
- 引入文件
import HTML5Backend from 'react-dnd-html5-backend';
import { DragDropContext, DragSource, DropTarget } from 'react-dnd';
- 拖拽源組件
拖拽源組件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
// 設(shè)置分析指標(biāo)彈層:拖拽源
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,
}));
}
}
- 拖拽目標(biāo)組件
拖拽目標(biāo)組件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>
拖拽目標(biāo)組件js
// 拖拽到的目標(biāo)組件
const chooseListTarget = {
drop(props, monitor) {
props.onDrop(monitor.getItem());
}
};
// 設(shè)置分析指標(biāo)彈層:拖拽x軸接受區(qū)域組件
@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軸選中內(nèi)容
@autobind
deleteXData() {
this.props.delXData();
}
render() {
const { connectDropTarget } = this.props;
return connectDropTarget(tmpls.AxisXTargetArea(this.state, this.props, this, {
styles,
}));
}
}
- 拖拽組件在根組件中的使用
使用DragDropContext包裹根組件
拖拽結(jié)束后交互處理
- 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 {
...
//拖動(dòng)結(jié)束后的操作
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,
}
});
}
};
}
...
}