以前,在React中实现拖放功能首选 React-DnD 库。由于该库具有强大的功能并且对于 React 开发人员来说易于使用,因此它被广泛推荐。
然而,现在出现了一个新的竞争者,提供了一个更强大、更好、更易于学习的解决方案:Dnd Kit。
虽然必须承认 React-DnD 仍然是一个不错的库,但 Dnd Kit 提供了许多优点,使其成为一个具有吸引力的替代方案。
例如,在功能方面,Dnd Kit 相对于 React-DnD 提供了许多改进。它更强大、更高效,并提供更好的用户体验。然而,选择哪个库最适合个人开发者的需求,取决于个人开发者自己的决定。
如果你问我,我更喜欢 Dnd Kit,也最常用它,这就是我写这篇文章让你也熟悉它的原因。
请记住,我遵循了官方文档,因此代码看起来是相同的。但我已尽力以尽可能简单的方式解释了这个概念。
此外,未来还将有一系列的文章,我将在其中解释一些复杂的示例,所以请关注我以获取更新,以便在我发布下一篇文章时得到通知。
现在让我们继续进行。
为什么选择 Dnd Kit ?
根据官方网站介绍,Dnd Kit 是一个轻量级、模块化、高性能、易于访问和可扩展的 React 拖放工具包。
它可以让你轻松拖放组件。
说到您可以创建的内容,实际上有大量的示例。其中一些最好的示例如下:
1. 看板
2. 跳棋游戏
3. 纸牌游戏
很酷吧?
同样,您也可以根据自己的喜好实现任何拖放功能。
因此,让我们深入研究并使用 Dnd Kit。
在 React 应用程序中使用 Dnd Kit
首先,我们必须安装 Dnd Kit。
在 React 项目中安装 Dnd Kit 非常简单。
1. 安装
首先,您必须使用标准命令创建一个 React 应用程序。
lua
npx create-react-app appname
译者注: 这里推荐使用更轻便、更快捷的vite,初始化命令: npm create vite
然后就可以安装 Dnd Kit 软件包了。为此,您只需安装核心库,它包含了您所需的大部分主要功能。
请在 React 应用程序中运行以下命令。
bash
npm install @dnd-kit/core
还有一些 Dnd 工具包,即修改器和可排序包,我们将在以后的文章中使用。
2. 了解 Dnd Kit 的工作原理
首先,请允许我解释一下 Dnd Kit 库背后的一些基本概念。
在使用 Dnd Kit 之前,您应该熟悉 React 中的 ref。如果您不知道,这里有相关文档。
现在让我们继续进行。
要使用 Dnd Kit 库,您需要定义两个组件:一个 Draggable 组件和一个 Droppable 组件。
Draggable 组件是可以拖动的元素,而 Droppable 组件则是可以放置 Draggable 组件的地方。
最后,为确保 Draggable 和 Droppable 组件之间的交互,这两个组件都必须置于 DndContext 组件内,后者充当父组件。
这样,DndContext 组件就可以管理两个组件之间的交互,并提供一个集中的地方来处理拖放功能。
以下是我上面解释内容的示例代码:
jsx
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 父组件和两个附加组件(Draggable、 Droppable)在其中。
3. 一个拖放示例
现在,您已经了解了 Dnd Kit 的一些基本概念,让我们举一个简单的例子。
在此之前,先让我向大家展示一下我们正在创造的东西。
在这里,左边一列由一个 Draggable 组件组成,右边一列由一个 Droppable 组件组成。
因此,让我们创建这两个组件。
创建 Draggable 组件
在 React 应用程序的 src 文件夹中新建一个名为 Draggable.jsx
的文件,然后粘贴下面的代码。
jsx
import React from 'react';
import { useDraggable } from '@dnd-kit/core';
export function Draggable(props) {
const { attributes, listeners, setNodeRef, transform } = useDraggable({
id: 'draggable',
});
const style = transform ? {
transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
} : undefined;
return (
<button ref={setNodeRef} style={style} {...listeners} {...attributes}>
{props.children}
</button>
);
}
在这里,我们定义了一个名为 Draggable 的 React 组件,它使用 Dnd Kit 库实现了可拖动元素的功能。代码从 @dnd-kit/core 库中导入了 useDraggable 钩子,用于为组件提供拖放功能。
然后,我们使用了 "useDraggable "钩子,该钩子会返回一个对象,其中包含几个用于实现可拖动功能的属性。
该对象包含以下属性:
- attributes: 一个对象,包含使组件可拖动所需的 HTML 属性
- listeners: 包含用户拖动组件时触发的事件监听器的对象
- setNodeRef: 用于设置组件 DOM 节点引用的函数
- transform: 一个对象,包含组件当前的 x 和 y 移位(以像素为单位)
"Draggable" 组件使用 "transform" 属性对组件应用平移。这是通过创建一个包含平移的 "style" 对象,并使用 "style" 属性将其应用于组件来完成的。
最后,我们定义了一个按钮元素,通过 "useDraggable "钩子中的 "setNodeRef "函数设置 DOM 节点的ref引用。该钩子的 "listeners" 和 "attributes" 对象分别使用 "...listeners" 和 "...attributes" 展开语法,将属性展开到组件上。
创建 Droppable 组件
现在,在 React 应用程序的 src 文件夹中新建一个名为 Droppable.jsx
的文件,并粘贴下面的代码。
jsx
import React from 'react';
import { useDroppable } from '@dnd-kit/core';
export function Droppable(props) {
const { isOver, setNodeRef } = useDroppable({
id: 'droppable',
});
const style = {
color: isOver ? 'blue' : undefined,
};
return (
<div ref={setNodeRef} style={style}>
{props.children}
</div>
);
}
在这里,useDroppable 钩子会返回一个包含两个属性的对象:
- isOver: 布尔值,表示可拖动组件当前是否位于可下垂组件的上方
- setNodeRef: 用于设置组件 DOM 节点引用的函数
那么代码就很简单了,如果可拖动组件位于可下垂组件的上方,那么 isOver 将为 true,因此蓝色将被应用。
创建父组件
请记住,我们必须创建一个包含这两个组件的父组件。
现在,让我们来创建它。
jsx
import React, { useState } from 'react';
import { DndContext } from '@dnd-kit/core';
import './App.css'
import { Droppable } from './Droppable';
import { Draggable } from './Draggable';
function App() {
const [isDropped, setIsDropped] = useState(false);
const draggableMarkup = (
<Draggable >
<div className='drag_item'>
Drag me
</div>
</Draggable>
);
return (
<DndContext onDragEnd={handleDragEnd}>
<div className='section'>
<div className='draggable'>
{!isDropped ? draggableMarkup : null}
</div>
<div className='draggable'>
<Droppable>
{isDropped ? draggableMarkup : 'Drop here'}
</Droppable>
</div>
</div>
</DndContext>
);
function handleDragEnd(event) {
if (event.over && event.over.id === 'droppable') {
setIsDropped(true);
}
}
}
export default App;
在 App 组件中,我们定义了一个状态变量 isDropped,用于跟踪可拖动项目是否已被拖放到可下放区域。
简单来说,我们有一些条件,要么显示可拖动的项目,要么显示一个消息,指示可以放置项目的位置。
在主渲染函数中,代码返回一个 DndContext 组件,并将回调函数 handleDragEnd 作为 prop 传递。当拖放操作完成时,将调用该回调函数。然后,我们有两个带有类名 "draggable" 的 div,用于应用相同的样式。
第一个 div 的子组件是 draggableMarkup 组件,但仅当 isDropped 为 false 时才显示。第二个 div 的子组件是 Droppable 组件。如果 isDropped 为 true,则显示 draggableMarkup 组件,否则显示文本 "Drop here"。
最后,handleDragEnd 函数检查 event.over 属性是否存在,以及 event.over 对象的 id 是否为 "droppable"。如果是,则通过调用 setIsDropped(true) 更新状态。
为你的React应用添加样式
最后,我们需要为我们的 React 应用程序应用样式。为此,您可以使用任何 CSS 框架,但我将简单地在 src 文件夹内创建一个新的 App.css 文件,并将以下代码添加到其中。
css
.section {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-color: rgb(37, 148, 251);
}
.draggable {
display: flex;
align-items: center;
justify-content: center;
width: 20rem;
height: 20rem;
background-color: #9749FF;
margin-right: 10px;
color: white;
}
.drag_item {
padding: 5px 10px;
width: 8rem;
height: auto;
color: black;
background-color: white;
}
就是这样,现在你可以运行应用程序并查看输出结果了。
希望你喜欢。
就这样--谢谢。
此外,未来还会有一系列关于 Dnd Kit 的文章,请务必关注我。
如侵则删