由于工作需要用到了拖拽功能,所以用到了react-dnd插件,简单封装了一个可公用的组件。

首先安装:

npm i react-dnd -S

npm i react-dnd-html5-backend -S

npm i immutability-helper -S // 非拖拽必须,此处为了方便

公用组件,可直接copy的部分,DragableComp.jsx:

import React from "react"

import { DragSource, DropTarget } from "react-dnd"

let dragingIndex = -1

const Comp = ({ connectDragSource, connectDropTarget, children }) => {

const style = {

cursor: "move"

}

return connectDragSource(

connectDropTarget(

{children}
)

)

}

const cardSource = {

beginDrag(props) {

dragingIndex = props.index

return {

index: props.index

}

}

}

const cardTarget = {

drop(props, monitor) {

const dragIndex = monitor.getItem().index

const hoverIndex = props.index

if (dragIndex === hoverIndex) {

return

}

props.moveRow(dragIndex, hoverIndex)

monitor.getItem().index = hoverIndex

}

}

const DragableComp = DropTarget("row", cardTarget, (connect, monitor) => ({

connectDropTarget: connect.dropTarget(),

isOver: monitor.isOver()

}))(

DragSource("row", cardSource, (connect) => ({

connectDragSource: connect.dragSource()

}))(Comp)

)

export default DragableComp

需要用到拖拽的父组件,最大的盒子,也就是它的子元素需要拖拽,父组件Parent.jsx:

import React, { useState } from "react"

import { DndProvider } from "react-dnd"

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

import Children from "./Children"

import update from "immutability-helper"

const Parent = () => {

// 被拖拽的几项子组件的数组

const [data, setData] = useState([1, 2, 3])

// 使用了immutability-helper插件提供的方法,可原样copy,也可自定义拖拽事件

const moveRow = (dragIndex, hoverIndex) => {

const dragRow = data[dragIndex]

const temp = update(data, {

$splice: [

[dragIndex, 1],

[hoverIndex, 0, dragRow]

]

})

setData([...temp])

}

return (

// 被拖拽的子元素需要被包裹在中

{data.map((item, index) => (

))}

)

}

export default Parent

接下来,是每一项能被拖拽的子组件Children.jsx:

import React from "react"

import { DragableComp } from "@/components"

const Children = ({ item,index, moveRow }) => {

return (

// index和moveRow方法提供给通用组件DragableComp使用

{/* 自定义被拖拽的每一项子组件 */}

style={{

background: "red",

height: 100,

marginBottom: 10

}}

>

{item}

)

}

export default Children

以上就是一个简易公用拖拽组件的封装以及如何使用的demo

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐