react dnd 实现拖拽功能,一个列表拖到另一个列表

 

1、拖拽组件封装

import React, { useState, useEffect } from 'react'

import { DndProvider, useDrop, useDrag } from 'react-dnd'

import HTML5Backend from 'react-dnd-html5-backend'

 

import { Row, Col, Card } from 'antd'

 

function DragPanel(props) {

 

const { dragItem, handleDrag, dragProps, firstCount } = props;

 

// 定义拖拽接收组件数据

const [dustbins, setDustbins] = useState([])

 

useEffect(() => {

if (dragProps) {

setDustbins(dragProps)

}

}, [dragProps])

 

function handleDrop(data) {

// console.log(data)

handleDrag(data)

}

 

function renderItem(item) {

return dragItem(item)

}

 

// 拖拽接收组件

function Bin(props) {

 

const { list, type, title, accept, onDrop, style } = props;

 

const [more, setMore] = useState(false);

 

// 定义拖动源

const [boxes] = useState(list.map(item => {

return { dragItem: item, type: type }

}))

 

const [{ isOver, canDrop }, drop] = useDrop({

accept,

drop: onDrop,

collect: (monitor) => ({

isOver: monitor.isOver(),

canDrop: monitor.canDrop(),

}),

})

const isActive = isOver && canDrop

 

let cardStyle = { ...style }

let alertType = null

if (isActive) {

cardStyle.boxShadow = "0px 0px 12px #1890ff";

alertType =

松开鼠标拖拽至此

} else if (canDrop) {

cardStyle.boxShadow = "0px 0px 12px #91d5ff";

alertType =

可拖拽

}

return (

{canDrop ? alertType : null}

{boxes.map(({ dragItem, type }, index) => {

if (more) {

return

}

if (index < (firstCount ? firstCount : 5)) {

return

}

return

})}

{

boxes.length > (firstCount ? firstCount : 5) ?

: null

}

)

}

 

// 可拖拽组件

function Box(props) {

 

const { dragItem, type } = props;

 

const [{ opacity }, drag] = useDrag({

item: { dragItem, type },

collect: (monitor) => ({

opacity: monitor.isDragging() ? 0.4 : 1,

}),

})

return (

{renderItem(dragItem ? dragItem : {})}

)

}

 

return (

{dustbins.map((dustbin, index) => (

key={index}

list={dustbin.list}

type={dustbin.type}

style={dustbin.style}

title={dustbin.title}

accept={dustbin.accepts}

onDrop={(item) => handleDrop({ dragItem: { ...item.dragItem }, dragTarget: dustbin.type })}

/>

))}

)

}

export default DragPanel

 

 

2、使用组件

 

import React from 'react'

import DragPanel from './index'

 

const ItemTypes = {

NEW: 'new',

DEAL: 'dear',

FINISH: 'finish',

}

 

function DragDemo(props) {

 

const taskList = {

new: [

{ id: 1, name: "11111" },

{ id: 2, name: "11111222" },

{ id: 3, name: "11111333" }

],

dear: [

{ id: 4, name: "1111144" },

{ id: 5, name: "1111122255" },

{ id: 6, name: "1111133366" },

{ id: 7, name: "111114477" },

{ id: 8, name: "11111222558" },

],

finish: [

{ id: 9, name: "1111144999" },

{ id: 10, name: "1111122251110" },

]

}

 

const dragProps = [

{

accepts: [], //接收拖拽类型

type: ItemTypes.NEW, //列表数据类型

style: { background: '#EDF5D0' },

title: "待办",

list: taskList[ItemTypes.NEW], //列表数据

},

{

accepts: [ItemTypes.NEW],

type: ItemTypes.DEAL,

title: "处理中",

style: { background: '#F5EED0' },

list: taskList[ItemTypes.DEAL]

},

{

accepts: [ItemTypes.NEW, ItemTypes.DEAL],

type: ItemTypes.FINISH,

title: "结束",

list: taskList[ItemTypes.FINISH]

},

]

 

function handleDrag(data) {

console.log(data)

}

 

function dragItem(props) {

return props.name

}

 

return

}

 

export default DragDemo

 

3、实现结果

react dnd 实现拖拽功能,一个列表拖到另一个列表_第1张图片

 

这里拖拽之后位置没有变化是因为没有处理数据,handleDrag方法中就是用来处理拖拽结果的 ,大部分需求是拖拽之后会调用api修改数据然后获取最新数据展示,所以不需要前端修改位置,api修改已经改变了源数据

你可能感兴趣的:(前端)