拖拽组件示例
演示 Draggable 组件:包裹单个子元素,基于 @dnd-kit 自由拖拽。
沙盒演示
三张相互独立的可拖拽卡片,每个 Draggable 各自持有独立的 DndContext,互不影响。
卡片 A
卡片 B
卡片 C
典型用法
用 Draggable 包裹任意单个元素(div、button 等)即可拖拽。
按住并拖动按钮即可移动它。
Draggable 组件使用说明
概述
src/common/components/Draggable.tsx 基于 @dnd-kit/core,把任意单个子元素变成可拖拽对象:内部用 useState 记录位置,useDraggable + MouseSensor(移动 5px 才触发)捕获拖拽,onDragEnd 时累加位移。
基本用法
import Draggable from "@/common/components/Draggable";
<Draggable>
<div className="rounded-lg border px-4 py-2">拖拽我</div>
</Draggable>
| Prop | 类型 | 必填 | 说明 |
|---|---|---|---|
| children | React.ReactNode | 是 | 被拖拽的子元素,必须是单个元素(内部用 React.Children.only) |
| asChild | boolean | 否 | 预留;当前始终按 asChild 模式把拖拽属性合并到子元素 |
工作原理
useDraggable提供listeners(onPointerDown等)、attributes(role/`aria-*)、setNodeRef与transform`。DraggableContainer通过AsChild把这些属性连同ref、style(transform+cursor)合并到子元素上。- 拖拽中
transform为本次拖拽的相对位移,叠加到已提交的position上;onDragEnd把位移累加回position。
注意事项
- 子元素请用
className设置样式,不要用内联style,否则会覆盖组件注入的transform。 - 每个
Draggable拥有独立的DndContext,多个实例可并存且互不干扰。 - 目前拖拽 id 写死为
"box",如需在同一DndContext下管理多个可拖拽对象,需改为动态 id。