返回 1. 安装
4. 使用
5. 使用
React 中使用拖拽让你轻松玩转界面交互
前端
2023-09-02 15:15:39
前言
在 HTML5 标准出来之前,实现拖拽的大致思路是监听鼠标移动相关事件,来拖动目标元素到页面的任意位置,这要求目标元素必须满足绝对定位、脱离文档流才可以被移动,伪代码如下:
<div id="target" style="position: absolute;">
<p>拖拽我</p>
</div>
<script>
const target = document.getElementById('target');
let isDragging = false;
let offsetX = 0;
let offsetY = 0;
target.addEventListener('mousedown', (e) => {
isDragging = true;
offsetX = e.clientX - target.offsetLeft;
offsetY = e.clientY - target.offsetTop;
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) {
return;
}
target.style.left = e.clientX - offsetX + 'px';
target.style.top = e.clientY - offsetY + 'px';
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
</script>
这种方式虽然简单,但也有不少缺点:
- 需要手动计算元素的偏移量,容易出错。
- 无法实现元素之间的拖拽排序。
- 不支持触屏设备。
为了解决这些问题,HTML5 标准引入了新的拖拽 API,使得拖拽操作变得更加简单和高效。
React 中的拖拽
React 中的拖拽功能主要通过 react-dnd
库来实现,它提供了丰富的 API 和组件,可以轻松实现各种拖拽操作。
1. 安装 react-dnd
库
npm install react-dnd --save
2. 创建可拖拽组件
首先,需要创建一个可拖拽组件,可以使用 react-dnd
提供的 Draggable
组件。
import { Draggable } from 'react-dnd';
const DraggableItem = (props) => {
const { id, text, onDragStart, onDragEnd } = props;
return (
<Draggable
id={id}
type="ITEM"
onDragStart={onDragStart}
onDragEnd={onDragEnd}
>
<div>{text}</div>
</Draggable>
);
};
在 Draggable
组件中,需要指定 id
、type
、onDragStart
和 onDragEnd
属性。
id
属性是元素的唯一标识。type
属性是元素的类型,可以是任意字符串。onDragStart
属性是拖拽开始时的回调函数。onDragEnd
属性是拖拽结束时的回调函数。
3. 创建目标组件
接下来,需要创建一个目标组件,可以使用 react-dnd
提供的 Droppable
组件。
import { Droppable } from 'react-dnd';
const DroppableArea = (props) => {
const { onDrop, children } = props;
return (
<Droppable
accept="ITEM"
onDrop={onDrop}
>
{children}
</Droppable>
);
};
在 Droppable
组件中,需要指定 accept
和 onDrop
属性。
accept
属性是目标组件可以接受的拖拽元素的类型。onDrop
属性是拖拽元素被放置到目标组件时的回调函数。
4. 使用 react-dnd
的 Hooks
为了简化拖拽操作,react-dnd
提供了几个 Hooks,可以让我们更轻松地使用拖拽功能。
useDrag
Hook:用于获取拖拽元素的 props。useDrop
Hook:用于获取目标组件的 props。
import { useDrag, useDrop } from 'react-dnd';
const DraggableItem = (props) => {
const { id, text } = props;
const [{ isDragging }, drag] = useDrag({
id,
type: 'ITEM',
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
return (
<div ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }}>
{text}
</div>
);
};
const DroppableArea = (props) => {
const { onDrop, children } = props;
const [{ isOver, canDrop }, drop] = useDrop({
accept: 'ITEM',
drop: (item) => {
onDrop(item);
},
collect: (monitor) => ({
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
}),
});
return (
<div ref={drop} style={{ border: isOver && canDrop ? '1px dashed blue' : '1px dashed gray' }}>
{children}
</div>
);
};
5. 使用 react-dnd
的 API
除了 Hooks 之外,react-dnd
还提供了一些 API,可以让我们更灵活地控制拖拽操作。
DragSource
:用于创建一个可拖拽元素。DropTarget
:用于创建一个目标组件。
import { DragSource, DropTarget } from 'react-dnd';
const DraggableItem = DragSource('ITEM', {
beginDrag(props) {
return { id: props.id };
},
endDrag(props, monitor) {
if (monitor.didDrop()) {
// 拖拽元素被放置到目标组件中
}
}
}, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(),
}));
const DroppableArea = DropTarget('ITEM', {
drop(props, monitor) {
const item = monitor.getItem();
// 拖拽元素被放置到目标组件中
}
}, (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
}));
结语
以上就是 React 中使用拖拽功能的详细介绍。通过 react-dnd
库,我们可以轻松实现各种拖拽操作,提升界面的交互性和用户体验。