useDraggable
使元素可拖拽,提供拖拽位置和状态管理。
函数签名
typescript
function useDraggable(
target: Ref<HTMLElement | null>,
options?: DraggableOptions
): {
x: Ref<number>
y: Ref<number>
isDragging: Ref<boolean>
position: Ref<{ x: number; y: number }>
style: ComputedRef<{ left: string; top: string; position: string }>
}
interface DraggableOptions {
initialX?: number
initialY?: number
preventDefault?: boolean
stopPropagation?: boolean
onStart?: (position: { x: number; y: number }) => void
onMove?: (position: { x: number; y: number }) => void
onEnd?: (position: { x: number; y: number }) => void
}参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
target | Ref<HTMLElement | null> | 是 | - | 目标元素的 ref |
options.initialX | number | 否 | 0 | 初始 X 坐标 |
options.initialY | number | 否 | 0 | 初始 Y 坐标 |
options.preventDefault | boolean | 否 | true | 是否阻止默认行为 |
options.stopPropagation | boolean | 否 | true | 是否阻止事件冒泡 |
options.onStart | function | 否 | - | 开始拖拽回调 |
options.onMove | function | 否 | - | 拖拽中回调 |
options.onEnd | function | 否 | - | 结束拖拽回调 |
返回值
| 类型 | 说明 |
|---|---|
{ x, y, isDragging, position, style } | 拖拽状态和位置信息 |
工作原理
初始化:
- 创建 x、y 坐标的响应式 ref(初始值为 options 中的 initialX/Y)
- 创建 isDragging 状态 ref
mousedown 事件:
- 记录鼠标按下时的起始坐标
- 记录元素的初始位置
- 设置 isDragging 为 true
- 添加 document 级别的 mousemove 和 mouseup 监听器
- 调用 onStart 回调
mousemove 事件:
- 计算鼠标移动的距离
- 更新元素位置:新位置 = 初始位置 + 移动距离
- 更新 x、y ref 的值
- 调用 onMove 回调
mouseup 事件:
- 移除 mousemove 和 mouseup 监听器
- 设置 isDragging 为 false
- 调用 onEnd 回调
计算样式:
- 返回 computed ref,自动生成 CSS 样式
{ left: '${x}px', top: '${y}px', position: 'fixed' }
清理:组件卸载时自动移除事件监听器
将 style 绑定到元素即可实现拖拽效果。