Skip to content

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
}

参数

参数名类型必填默认值说明
targetRef<HTMLElement | null>-目标元素的 ref
options.initialXnumber0初始 X 坐标
options.initialYnumber0初始 Y 坐标
options.preventDefaultbooleantrue是否阻止默认行为
options.stopPropagationbooleantrue是否阻止事件冒泡
options.onStartfunction-开始拖拽回调
options.onMovefunction-拖拽中回调
options.onEndfunction-结束拖拽回调

返回值

类型说明
{ x, y, isDragging, position, style }拖拽状态和位置信息

工作原理

  1. 初始化

    • 创建 x、y 坐标的响应式 ref(初始值为 options 中的 initialX/Y)
    • 创建 isDragging 状态 ref
  2. mousedown 事件

    • 记录鼠标按下时的起始坐标
    • 记录元素的初始位置
    • 设置 isDragging 为 true
    • 添加 document 级别的 mousemove 和 mouseup 监听器
    • 调用 onStart 回调
  3. mousemove 事件

    • 计算鼠标移动的距离
    • 更新元素位置:新位置 = 初始位置 + 移动距离
    • 更新 x、y ref 的值
    • 调用 onMove 回调
  4. mouseup 事件

    • 移除 mousemove 和 mouseup 监听器
    • 设置 isDragging 为 false
    • 调用 onEnd 回调
  5. 计算样式

    • 返回 computed ref,自动生成 CSS 样式
    • { left: '${x}px', top: '${y}px', position: 'fixed' }
  6. 清理:组件卸载时自动移除事件监听器

将 style 绑定到元素即可实现拖拽效果。