请选择 进入手机版 | 继续访问电脑版
切换风格

Sunset glow Snow NewYear London Flowers Wizard California Cloud Sky Lavender City Black Beige Dragon

1万

主题

1万

帖子

3万

积分

金牌会员

Rank: 6Rank: 6

吾爱币
25109
在线时间
9 小时
注册时间
2020-3-25

论坛新星

react-dnd 拖拽排序[复制链接]
发表于 3 天前 | 显示全部楼层 |阅读模式
标签:官方文档 上下文 top hal default 样式 back wrap drag
开始

最近刚刚做完自定义表单的组件,分享一下拖拽排序。
效果图


react-dnd使用说明

必须是这样格式的,不然会报 找不到上下文
   准备工作

官方文档
https://react-dnd.github.io/react-dnd/about
安装react-dnd、react-dnd-html5-backend
npm install react-dnd react-dnd-html5-backend开始开发

项目是基于ts的,不需要可自行删除
定义父组件

const Drag:React.FC = props => { return (  {/* DndProvider组件提供了react-dnd的功能,必须通过backend绑定HTML5Backend*/}   
)}export default Drag定义内容组件

const DragSortComponent:React.FC = props => { const [list,setList] = useState(List) const [itemClass, setItemClass] = useState({ key: null, value: ‘‘, }) // 拖拽后的值 const sortItems = useRef({ dragRow: {}, placeRow: {}, posi: ‘‘, }) // 拖拽结束后的方法 const onDrop = (item: any, monitor: DropTargetMonitor) => { const { dragRow, placeRow, posi } = sortItems.current let _map: any[] = JSON.parse(JSON.stringify(list)) let index1 = _map.findIndex(v => v.id === dragRow.id) // 拖拽的itemIndex _map.splice(index1, 1) // 先删掉拖拽的,在获取放置的 let index = _map.findIndex(v => v.id === placeRow.id) // 放置的itemIndex if (index !== -1 && index1 !== -1) { _map.splice(posi === ‘bottom‘ ? index + 1 : index, 0, dragRow) setList(() => _map) } } // DragSortItemComponent组件是通用排序组件,所以需要在父组件在定义一个useDrop,来改变数据 必须挂载在父级div const [, drop] = useDrop({ accept: ‘sort‘, // 必须和拖拽的accept一致 drop: onDrop, collect: monitor => ({ isOver: monitor.isOver({ shallow: true }), canDrop: monitor.canDrop(), }), }) const onItemDragClass = (key:number,value:string) => { if (itemClass.value !== value) { setItemClass(() => { let data = { key, value } return data }) } } const onSortItemChange = (dragRow: any, placeRow: any, posi: string) => { sortItems.current = { dragRow, placeRow, posi } } return (  { list.map(v => (  {v.name}
  )) }
)}定义拖拽排序组件

/** * 通用拖拽排序的容器 * @param row 当前行 * @param onItemDragClass 拖拽过程的样式 top | bottom * @param onSortItemChange 拖拽结束后返回的值 dragRow 当前拖拽 placeRow 放置的,posi 位置 top | bottom * @param keyName 键名 */type IProps = { row: any, onItemDragClass: (key:number,value:string) => void, onSortItemChange: (dragRow: any, placeRow: any, posi: string) => void // 排序后 keyName: string}const DragSortItemComponent:React.FC = props => { const { row,onItemDragClass,onSortItemChange,keyName } = props const ref = useRef(null) /** * 拖拽容器 */ const [, drop] = useDrop({ // 定义拖拽的类型 accept: ‘sort‘, drop: (item, monitor) => { const didDrop = monitor.didDrop() if (didDrop) { return } }, canDrop: (item, mointor) => { // 阻止默认拖拽释放 onItemDragClass(row[keyName], ‘‘) return false }, hover: (item: any, monitor) => { const didHover = monitor.isOver({ shallow: true }) if (didHover) { // 拖拽目标的id const dragIndex = item[keyName] // 放置目标id 可以用index | id 只要是number,数据里唯一的就可以 const hoverIndex = row[keyName] // 如果一样不处理 if (dragIndex === hoverIndex) { onItemDragClass(row[keyName], ‘‘) return } // 获取放置的位置 const hoverBoundingRect = ref.current?.getBoundingClientRect() as DOMRect // 获取放置的Y轴中点 const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2 // 获取拖拽目标偏移量 const clientOffset = monitor.getClientOffset() as XYCoord const hoverClientY = clientOffset.y - hoverBoundingRect.top if (dragIndex !== hoverIndex) { if (hoverMiddleY < hoverClientY) { onItemDragClass(row[keyName], ‘bottom‘) } else { onItemDragClass(row[keyName], ‘top‘) } // 如果不做成通用拖拽容器,把参数存起来,把这个放在useDrag的end方法里, onSortItemChange(item, row, hoverMiddleY < hoverClientY ? ‘bottom‘ : ‘top‘) } } }, collect: monitor => ({ isOver: monitor.isOver({ shallow: true }), canDrop: monitor.canDrop(), }), }) /** * 定义拖拽 * isDragging 是否拖拽 */ const [{ isDragging }, drag] = useDrag({ item: { ...row, type: ‘sort‘}, end: () => { // onSortItemChange(item, row, hoverMiddleY < hoverClientY ? ‘bottom‘ : ‘top‘) }, collect: monitor => ({ isDragging: monitor.isDragging(), didDrop: monitor.isDragging(), }), }) drop(drag(ref)) return (  {props.children}
)}react-dnd 拖拽排序
标签:官方文档 上下文 top hal default 样式 back wrap drag
原文地址:https://www.cnblogs.com/feiyu159/p/14267401.html




上一篇:Selenium 3 常用API
下一篇:Java8对多个字段排序
回复

使用道具 举报

53

主题

2821

帖子

5698

积分

金牌会员

Rank: 6Rank: 6

吾爱币
2877
在线时间
0 小时
注册时间
2020-7-7
发表于 3 天前 | 显示全部楼层
一直在看
回复

使用道具 举报

244

主题

3045

帖子

6335

积分

金牌会员

Rank: 6Rank: 6

吾爱币
3290
在线时间
0 小时
注册时间
2020-6-28

论坛新星

发表于 前天 12:01 | 显示全部楼层
very good
回复

使用道具 举报

232

主题

3064

帖子

6360

积分

金牌会员

Rank: 6Rank: 6

吾爱币
3296
在线时间
0 小时
注册时间
2020-6-28

论坛新星

发表于 昨天 02:51 | 显示全部楼层
楼猪V5啊
回复

使用道具 举报

235

主题

3003

帖子

6241

积分

金牌会员

Rank: 6Rank: 6

吾爱币
3238
在线时间
0 小时
注册时间
2020-6-28

论坛新星

发表于 4 小时前 | 显示全部楼层
在撸一遍。。。
回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|Archiver|手机版|小黑屋|吾爱分享-享你所想 ( 黔ICP备18007665号-2 )|网站地图

GMT+8, 2021-1-17 08:20 , Processed in 1.923369 second(s), 60 queries .

Powered by 52Fenxiang.Top

© 2001-2020 Comsenz Inc.

返回顶部