最近在项目上有个模块需要实现拖拽功能,选了很久的拖拽组件,最后选择了dnd-kit组件库,原因在于这个组件比较新,并且近期还在维护,还有相对应的学习文档可以查看。
dnd-kit GitHub链接:https://github.com/clauderic/dnd-kit
dnd-kit 官方学习文档链接:https://docs.dndkit.com/
第一步:安装
npm install @dnd-kit/core @dnd-kit/sortable
第一个库为dnd-kit的核心库,第二个库是可排序库。
第二步:导入
import {DndContext} from '@dnd-kit/core';
第三步:使用
dnd-kit使用起来其实是非常简单的,在使用之前我们可以考虑一下实现拖拽总共分几部分?拖拽可以粗略的分为三个部分组成,整体的拖拽容器(可以在这个容器里进行拖拽)、可落下的容器(具有接收拖拽组件的容器)、可拖拽的组件(拖拽目标),这三部分正好可以通过dnd-kit去实现。
以下实现的是一个简单的拖拽demo。
根据官方文档可以看出具体的代码结构,最外层一定是由<DndContext></DndContext>组件进行包裹,在里面的才组件才可以进行拖拽。
import React from 'react';
import {DndContext} from '@dnd-kit/core';
import {Draggable} from './Draggable';
import {Droppable} from './Droppable';
function App() {
return (
<DndContext>
<Draggable /> //拖拽组件
<Droppable /> //可落下的容器组件
</DndContext>
)
}
DndContext的属性如下,可以看到有onDragStart那几个函数方法。
interface Props {
announcements?: Announcements;
autoScroll?: boolean;
cancelDrop?: CancelDrop;
children?: React.ReactNode;
collisionDetection?: CollisionDetection;
layoutMeasuring?: Partial<LayoutMeasuring>;
modifiers?: Modifiers;
screenReaderInstructions?: ScreenReaderInstructions;
sensors?: SensorDescriptor<any>[];
onDragStart?(event: DragStartEvent): void;
onDragMove?(event: DragMoveEvent): void;
onDragOver?(event: DragOverEvent): void;
onDragEnd?(event: DragEndEvent): void;
onDragCancel?(): void;
}
我使用的onDragEnd方法,打印结果如下,其他的属性可以自行去打印试一下:
demo源代码
主文件代码
import React, {useState} from 'react'
import {DndContext} from "@dnd-kit/core";
import {Draggable} from "./Draggable";
import {Droppable} from "./Droppable";
export default function App() {
const containers = ['A', 'B', 'C','D','E'];
const [parent, setParent] = useState(null);
const draggableMarkup = (
<Draggable id="draggable">
<div style={{width:200,height:150,background:'pink',cursor:'move'}}>可拖拽组件</div>
</Draggable>
);
const handleDragEnd=(event)=> {
console.log(event,'-----------');
const {over} = event;
setParent(over ? over.id : null);
}
return (
<DndContext onDragEnd={handleDragEnd}>
<div style={{display:'flex',justifyContent: 'space-between',paddingTop:50}}>
{containers.map((id) => (
<Droppable key={id} id={id}>
<div style={{width:250,height:400,border:'1px solid #000'}}>
{parent === id ? draggableMarkup : '可落下的容器'}
</div>
</Droppable>
))}
</div>
{parent === null ? draggableMarkup : null}
</DndContext>
);
}
可落下容器组件代码
import React from 'react';
import {useDroppable} from '@dnd-kit/core';
export function Droppable(props) {
const {isOver, setNodeRef} = useDroppable({
id: props.id,
});
return (
<div ref={setNodeRef}>
{props.children}
</div>
);
}
可拖拽组件代码
import React from 'react';
import {useDraggable} from '@dnd-kit/core';
//拖拽组件
export function Draggable(props) {
const {attributes, listeners, setNodeRef, transform} = useDraggable({
id: props.id,
});
const style = transform ? {
transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
} : undefined;
return (
<div ref={setNodeRef} style={style} {...listeners} {...attributes}>
{props.children}
</div>
);
}
以上就是demo的全部代码了,剩下就可以自行发挥了,具体的一些方法和钩子需要去官方文档自行查看学习。