useDrag
一个拖拽操作管理 Hook,提供完整的拖拽功能,支持位置约束、网格对齐、轴限制等高级特性。自动处理鼠标事件和拖拽状态管理。
基础用法
🎯 基础拖拽
位置: (0, 0)
拖拽中: false
拖拽中: false
约束拖拽示例
🔒 约束拖拽
边界约束
水平拖拽
网格对齐
API 参考
参数
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
options | UseDragOptions | {} | 配置选项 |
UseDragOptions
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
initialPosition | Position | { x: 0, y: 0 } | 初始位置 |
axis | 'x' | 'y' | 'both' | 'both' | 拖拽轴限制 |
grid | [number, number] | - | 网格对齐,[x间距, y间距] |
boundary | Boundary | - | 拖拽边界限制 |
constrainToParent | boolean | false | 是否约束在父元素内 |
handle | string | - | 拖拽手柄选择器 |
disabled | boolean | false | 是否禁用拖拽 |
onDragStart | (state: DragState, event: MouseEvent) => void | - | 拖拽开始回调 |
onDrag | (state: DragState, event: MouseEvent) => void | - | 拖拽中回调 |
onDragEnd | (state: DragState, event: MouseEvent) => void | - | 拖拽结束回调 |
返回值
useDrag
返回一个数组,包含以下元素:
typescript
const [elementRef, dragState, startDrag, stopDrag, resetPosition, setPosition] = useDrag(options);
索引 | 名称 | 类型 | 说明 |
---|---|---|---|
0 | elementRef | Ref<HTMLElement | null> | 拖拽元素的引用 |
1 | dragState | ComputedRef<DragState> | 拖拽状态 |
2 | startDrag | (event: MouseEvent) => void | 手动开始拖拽 |
3 | stopDrag | () => void | 手动停止拖拽 |
4 | resetPosition | () => void | 重置位置 |
5 | setPosition | (x: number, y: number) => void | 设置位置 |
类型定义
typescript
export interface Position {
x: number;
y: number;
}
export interface Boundary {
left?: number;
top?: number;
right?: number;
bottom?: number;
}
export interface DragState {
position: Position;
isDragging: boolean;
startPosition: Position;
offset: Position;
}
export interface UseDragOptions {
initialPosition?: Position;
axis?: "x" | "y" | "both";
grid?: [number, number];
boundary?: Boundary;
constrainToParent?: boolean;
handle?: string;
disabled?: boolean;
onDragStart?: (state: DragState, event: MouseEvent) => void;
onDrag?: (state: DragState, event: MouseEvent) => void;
onDragEnd?: (state: DragState, event: MouseEvent) => void;
}
export type UseDragReturn = [
Ref<HTMLElement | null>,
ComputedRef<DragState>,
(event: MouseEvent) => void,
() => void,
() => void,
(x: number, y: number) => void,
];
使用场景
- 拖拽排序 - 列表项的拖拽排序
- 画布操作 - 图形编辑器中的元素拖拽
- 布局调整 - 可拖拽的面板和窗口
- 游戏开发 - 游戏中的拖拽交互
- 数据可视化 - 图表中的拖拽操作
高级用法
拖拽手柄
typescript
const [dragRef, dragState] = useDrag({
handle: ".drag-handle", // 只有 .drag-handle 元素可以拖拽
});
约束到父元素
typescript
const [dragRef, dragState] = useDrag({
constrainToParent: true, // 自动约束在父元素内
});
回调函数
typescript
const [dragRef, dragState] = useDrag({
onDragStart: (state, event) => {
console.log("开始拖拽", state.position);
},
onDrag: (state, event) => {
console.log("拖拽中", state.position);
},
onDragEnd: (state, event) => {
console.log("拖拽结束", state.position);
},
});
注意事项
- 需要将
elementRef
绑定到要拖拽的元素上 - 拖拽元素需要设置
position: absolute
或position: relative
- 使用
transform
来应用位置变化以获得更好的性能 - 网格对齐会自动调整位置到最近的网格点
- 边界约束会限制拖拽范围
- 组件卸载时会自动清理事件监听器