返回首页

拖拽组件示例

演示 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类型必填说明
childrenReact.ReactNode是被拖拽的子元素,必须是单个元素(内部用 React.Children.only)
asChildboolean否预留;当前始终按 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。