自己随手写了一个小案例,记录一下。

1、实现右边盒子内容拖到左边盒子里。
依赖 -- --
react-dnd
react-dnd-html5-backend
2、实现左边盒子资源的拖动
依赖 -- --
react-beautiful-dnd
(1) ---- index.js
import React, { Component } from "react";
import { DndProvider } from 'react-dnd'
import { HTML5Backend } from 'react-dnd-html5-backend'
import Dustbin from "./Dustbin";
import Box from "./Box";
import "./index.less";
class Home extends Component {
state = {
mainList: [
{id: 'item-6', content: 'aaaaaaaaa'},
{id: 'item-7', content: 'bbbbbbbbb'},
{id: 'item-8', content: 'ccccccccc'},
{id: 'item-9', content: 'ddddddddd'},
{id: 'item-10', content: 'eeeeeeeee'},
{id: 'item-11', content: 'fffffffff'},
],
sideList: [
{ id: "item-0", content: "hello" },
{ id: "item-1", content: "I" },
{ id: "item-2", content: "am" },
{ id: "item-3", content: "卡" },
{ id: "item-4", content: "特" },
{ id: "item-5", content: "洛" },
]
}
endPull = (opt) => {
const sideList = [...this.state.sideList, opt];
// alert('添加成功')
this.setState({ sideList })
}
reOrder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
onDragEnd = (result) => {
console.log(result)
if (!result.destination) return;
const sideList = this.reOrder(
this.state.sideList,
result.source.index,
result.destination.index
);
this.setState({ sideList })
};
render() {
return (
<div style={{ paddingLeft: 200, paddingTop: 50, display: 'flex' }} className='page-home'>
<DndProvider backend={HTML5Backend}>
<div>
<Dustbin sideList={this.state.sideList} switchSeat= {sideList => this.setState({ sideList })} />
</div>
<div style={{flex: 1, display: 'flex', flexWrap: 'wrap'}}>
{/* 案例实现的是循环里数据都能实现拖拽,所以要循环组件 */}
{
this.state.mainList.map(item => {
return (
<Box
key={item.id}
item={item}
endPull={this.endPull}
/>
)
})
}
</div>
</DndProvider>
</div>
);
}
}
export default Home
(2) -- -- Box.index
import React from "react";
import { DragSource } from "react-dnd";
let endPull = null;
const boxSource = {
/**
* 开始拖拽时触发当前函数
* @param {*} props 组件的 props
*/
beginDrag(props) {
// 返回的对象可以在 monitor.getItem() 中获取到
return {
// name: props.name,
};
},
/**
* 拖拽结束时触发当前函数
* @param {*} props 当前组件的 props
* @param {*} monitor DragSourceMonitor 对象
*/
endDrag(props, monitor) {
// 当前拖拽的 item 组件
// const item = monitor.getItem();
// 拖拽元素放下时,drop 结果
const dropResult = monitor.getDropResult();
// 如果 drop 结果存在,就弹出 alert 提示
if (dropResult) {
// alert(`You dropped ${item.name} into ${dropResult.name}!`);
if(!endPull) return;
endPull(props.item);
}
},
};
@DragSource(
// type 标识,这里是字符串 'box'
// ItemTypes.BOX,
'box',
// 拖拽事件对象
boxSource,
// 收集功能函数,包含 connect 和 monitor 参数
// connect 里面的函数用来将 DOM 节点与 react-dnd 的 backend 建立联系
(connect, monitor) => ({
// 包裹住 DOM 节点,使其可以进行拖拽操作
connectDragSource: connect.dragSource(),
// 是否处于拖拽状态
isDragging: monitor.isDragging(),
})
)
class Box extends React.Component {
componentDidMount() {
endPull = this.props.endPull;
}
render() {
const { connectDragSource } = this.props;
const { item } = this.props;
// 使用 connectDragSource 包裹住 DOM 节点,使其可以接受各种拖动 API, connectDragSource 包裹住的 DOM 节点才可以被拖动
return (
<div style={{display: 'flex'}}>
{
connectDragSource &&
connectDragSource(
<div key={item.key} style={{width: '200px', margin: '50px'}}>
<dl style={{width: '200px', height: '100px'}}>
<dt style={{height: '70px', background: 'pink'}}>图片</dt>
<dd style={{height: '30px', background: '#eee'}}>{item.content}</dd>
</dl>
</div>
)
}
</div>
);
}
}
export default Box;
(3) -- -- Dustbin.js
import React from "react";
import { DropTarget } from "react-dnd";
import { Collapse } from "antd";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
const { Panel } = Collapse;
const boxTarget = {
// 当有对应的 drag source 放在当前组件区域时,会返回一个对象,可以在 monitor.getDropResult() 中获取到
drop: () => ({ name: "Dustbin" }),
};
@DropTarget(
// type 标识,这里是字符串 'box'
// ItemTypes.BOX,
"box",
// 接收拖拽的事件对象
boxTarget,
// 收集功能函数,包含 connect 和 monitor 参数
// connect 里面的函数用来将 DOM 节点与 react-dnd 的 backend 建立联系
(connect, monitor) => ({
// 包裹住 DOM 节点,使其可以接收对应的拖拽组件
connectDropTarget: connect.dropTarget(),
// drag source是否在 drop target 区域
isOver: monitor.isOver(),
// 是否可以被放置
canDrop: monitor.canDrop(),
})
)
class Dustbin extends React.Component {
state = {
keyActive: "1",
periodList: [
{ id: 1, name: "测试1" },
{ id: 2, name: "测试2" },
{ id: 3, name: "测试3" },
],
};
onCollapseChange = (key) => {
if (key) {
this.setState({ keyActive: key });
}
};
reOrder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
onDragEnd = (result) => {
console.log(result);
if (!result.destination) return;
const sideList = this.reOrder(
this.props.sideList,
result.source.index,
result.destination.index
);
this.props.switchSeat(sideList);
};
render() {
const { connectDropTarget } = this.props;
const { sideList } = this.props;
const { keyActive, periodList } = this.state;
return (
<div
style={{ width: "200px", border: "1px solid gray", height: "500px" }}
>
<Collapse
accordion
ghost
className="collapse_wrap"
// activeKey={1}
activeKey={keyActive}
onChange={this.onCollapseChange}
>
{periodList &&
periodList.map((item, index) => {
return (
<Panel header={item.name} key={item.id} showArrow={false}>
<React.Fragment>
{connectDropTarget &&
connectDropTarget(
<div>
<DragDropContext
onDragEnd={this.onDragEnd}
>
<Droppable droppableId="droppable">
{(provided) => (
<div
ref={provided.innerRef}
{...provided.droppableProps}
>
{sideList.map((item, index) => (
<Draggable
// 这个key值必须是string类型, 不能是number, 想知道为什么,自己试下就知道了。
key={item.id}
draggableId={item.id}
index={index}
>
{(provided) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<span
style={{
display: "block",
height: "30px",
lineHeight: "30px",
borderBottom: "1px solid red",
paddingLeft: "10px",
}}
>
{item.content}
</span>
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</div>
)}
</React.Fragment>
{/* {
connectDropTarget &&
connectDropTarget(
<div className='class_hour_list'>
{
detailList.map(v => {
return (
<p key={v}>{v.name}</p>
)
})
}
</div>
)
} */}
</Panel>
);
})}
</Collapse>
</div>
);
}
}
export default Dustbin;
浙公网安备 33010602011771号