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

react

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 } = 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 [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 dragText = ''

if (isActive) {

cardStyle.background = 'darkgreen'

dragText = '松开鼠标拖拽至此'

} else if (canDrop) {

cardStyle.background = 'darkkhaki'

dragText = '可拖拽'

}

return (

<div ref={drop} >

<Card title={`${title}(${list.length})`} style={cardStyle}>

{dragText ? <div style={{ textAlign: "center", paddingBottom: 5 }}>{dragText}</div> : null}

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

return <Box key={index} dragItem={dragItem} type={type} />

})}

</Card>

</div>

)

}

// 可拖拽组件

function Box(props) {

const { dragItem, type } = props;

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

item: { dragItem, type },

collect: (monitor) => ({

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

}),

})

return (

<div ref={drag} style={{ opacity }}>

{renderItem(dragItem)}

</div>

)

}

return (

<DndProvider backend={HTML5Backend}>

<Row>

<div style={{ overflow: 'hidden', clear: 'both' }}>

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

<Col key={index} span={24 / dustbins.length} style={{ padding: 10 }}>

<Bin

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 })}

/>

</Col>

))}

</div>

</Row>

</DndProvider>

)

}

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 <DragPanel dragProps={dragProps} handleDrag={handleDrag} dragItem={dragItem} />

}

export default DragDemo

3、实现结果

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

以上是 react dnd 实现拖拽功能,一个列表拖到另一个列表 的全部内容, 来源链接: utcz.com/z/383161.html

回到顶部