Skip to content

useDraggable

类别
导出体积
1.37 kB
上次更改
5 months ago

使元素可拖动。

示例

选中浮动框

👋 拖动我!
我在 48, 80
无渲染组件
在 sessionStorage 中保存的位置
51, 150
👋 拖到这里!
触发拖动事件的元素
我在 56, 240
Not Use Captured Element
Dragging here will not work
61, 330

用法

vue
<script setup lang="ts">
import { useDraggable } from '@vueuse/core'
import { useTemplateRef } from 'vue'

const el = useTemplateRef<HTMLElement>('el')

// `style` 将作为 `left: ?px; top: ?px;` 的辅助计算属性
const { x, y, style } = useDraggable(el, {
  initialValue: { x: 40, y: 40 },
})
</script>

<template>
  <div ref="el" :style="style" style="position: fixed">
    拖动我!我在 {{ x }},{{ y }} 的位置
  </div>
</template>

设置 preventDefault: true 以覆盖浏览器中某些元素的默认拖放行为。

ts
const { x, y, style } = useDraggable(el, {
  preventDefault: true,
  // with `preventDefault: true`
  // you can disable the native behavior (e.g., for img)
  // and control the drag-and-drop, preventing the browser interference.
})

组件用法

vue
<template>
  <UseDraggable v-slot="{ x, y }" :initial-value="{ x: 10, y: 10 }">
    拖动我!我在 {{ x }},{{ y }} 的位置
  </UseDraggable>
</template>

对于组件的用法,还可以将附加属性 storageKeystorageType 传递给组件,并启用元素位置的持久化。

vue
<template>
  <UseDraggable storage-key="vueuse-draggable" storage-type="session">
    刷新页面后,我仍然在相同的位置!
  </UseDraggable>
</template>

类型声明

显示类型声明
typescript
export interface UseDraggableOptions {
  /**
   * 只有在直接点击元素时才开始拖动
   *
   * @default false
   */
  exact?: MaybeRefOrGetter<boolean>
  /**
   * 阻止事件的默认行为
   *
   * @default false
   */
  preventDefault?: MaybeRefOrGetter<boolean>
  /**
   * 阻止事件的传播
   *
   * @default false
   */
  stopPropagation?: MaybeRefOrGetter<boolean>
  /**
   * 是否在捕获阶段分发事件
   *
   * @default true
   */
  capture?: boolean
  /**
   * 要附加 `pointermove` 和 `pointerup` 事件的元素。
   *
   * @default window
   */
  draggingElement?: MaybeRefOrGetter<
    HTMLElement | SVGElement | Window | Document | null | undefined
  >
  /**
   * 用于计算边界的元素(如果未设置,将使用事件的目标)。
   *
   * @default undefined
   */
  containerElement?: MaybeRefOrGetter<
    HTMLElement | SVGElement | null | undefined
  >
  /**
   * 触发拖动事件的句柄
   *
   * @default target
   */
  handle?: MaybeRefOrGetter<HTMLElement | SVGElement | null | undefined>
  /**
   * 监听的指针类型。
   *
   * @default ['mouse', 'touch', 'pen']
   */
  pointerTypes?: PointerType[]
  /**
   * 元素的初始位置。
   *
   * @default { x: 0, y: 0 }
   */
  initialValue?: MaybeRefOrGetter<Position>
  /**
   * 拖动开始时的回调函数。返回 `false` 可以防止拖动。
   */
  onStart?: (position: Position, event: PointerEvent) => void | false
  /**
   * 拖动过程中的回调函数。
   */
  onMove?: (position: Position, event: PointerEvent) => void
  /**
   * 拖动结束时的回调函数。
   */
  onEnd?: (position: Position, event: PointerEvent) => void
  /**
   * 要在其上拖动的轴。
   *
   * @default 'both'
   */
  axis?: "x" | "y" | "both"
  /**
   * 禁用拖放。
   *
   * @default false
   */
  disabled?: MaybeRefOrGetter<boolean>
  /**
   * Mouse buttons that are allowed to trigger drag events.
   *
   * - `0`: Main button, usually the left button or the un-initialized state
   * - `1`: Auxiliary button, usually the wheel button or the middle button (if present)
   * - `2`: Secondary button, usually the right button
   * - `3`: Fourth button, typically the Browser Back button
   * - `4`: Fifth button, typically the Browser Forward button
   *
   * @see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button#value
   * @default [0]
   */
  buttons?: MaybeRefOrGetter<number[]>
}
/**
 * 使元素可拖动。
 *
 * @see https://vueuse.org/useDraggable
 * @param target
 * @param options
 */
export declare function useDraggable(
  target: MaybeRefOrGetter<HTMLElement | SVGElement | null | undefined>,
  options?: UseDraggableOptions,
):
  | {
      position: Ref<
        {
          x: number
          y: number
        },
        | Position
        | {
            x: number
            y: number
          }
      >
      isDragging: ComputedRef<boolean>
      style: ComputedRef<string>
      x: Ref<number, number>
      y: Ref<number, number>
    }
  | {
      position: Ref<
        {
          x: number
          y: number
        },
        | Position
        | {
            x: number
            y: number
          }
      >
      isDragging: ComputedRef<boolean>
      style: ComputedRef<string>
      x: Ref<number, number>
      y: Ref<number, number>
    }
export type UseDraggableReturn = ReturnType<typeof useDraggable>

源码

源码演示文档

贡献者

Anthony Fu
一纸忘忧
huiliangShen
Anthony Fu
IlyaL
丶远方
webfansplz
Shigma
wgh970312
IlyaL
Robin
Fernando Fernández
Alex Peshkov
Joona Tiinanen
GU Yiling
wangliangxin
Kazim Duran
Jessé Correia Lins
faga
vaakian X
Akiho Nagao
stefnotch
btea
guolao
vaakian X
Jelf
donotloveshampo
Julian Meinking
Jukka Raimovaara
wheat

更新日志

547f8 - fix: add capture prop to component (#4911)
7432f - feat(types): deprecate MaybeRef and MaybeRefOrGetter in favor of Vue's native (#4636)
dd316 - feat: use passive event handlers everywhere is possible (#4477)
59f75 - feat(toValue): deprecate toValue from @vueuse/shared in favor of Vue's native
0a9ed - feat!: drop Vue 2 support, optimize bundles and clean up (#4349)
7f25b - fix: draggable component not work with container (#4192)
e9938 - feat: add buttons option (#4084)
9f10a - fix: should ignore right clicks (#3850)
dee9a - feat: add disabled parameter (#3613)
55b94 - fix: avoid moving out of container (#3768)
bdd79 - fix: can not work well when parent element is scrollable (#3692)
08246 - fix: element can't relative parent element move (#3531)
c08e5 - feat: allowing calculations of bounds with fixed element (#3335)
6b670 - feat: improve component props (#3075)