useDraggable
使元素可拖动。
示例
选中浮动框
👋 拖动我!
我在 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('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>返回值
| 属性 | 类型 | 说明 |
|---|---|---|
x | Ref<number> | 当前 x 位置 |
y | Ref<number> | 当前 y 位置 |
position | Ref<{x, y}> | 当前位置信息对象 |
isDragging | ComputedRef<boolean> | 当前是否正在拖动 |
style | ComputedRef<string> | CSS 样式字符串,如 left: ?px; top: ?px; |
选项
ts
useDraggable(el, {
// 初始位置(默认值:{ x: 0, y: 0 })
initialValue: { x: 40, y: 40 },
// 限制拖动的轴:'x','y' 或 'both'(默认)
axis: 'both',
// 仅当直接点击元素时触发(默认:false)
exact: false,
// 阻止默认浏览器行为(默认:false)
preventDefault: true,
// 停止事件传播(默认:false)
stopPropagation: false,
// 使用事件捕获阶段(默认:true)
capture: true,
// 禁用拖动(默认:false)
disabled: false,
// 触发拖动的鼠标按钮(默认:[0] - 左键)
buttons: [0],
// 监听的指针类型(默认:['mouse', 'touch', 'pen'])
pointerTypes: ['mouse', 'touch', 'pen'],
// 自定义拖动把手元素(默认:目标元素)
handle: handleRef,
// 用于限制拖动边界的容器元素(默认:无)
containerElement: containerRef,
// 绑定 pointermove/pointerup 事件的元素(默认:window)
draggingElement: window,
// 回调函数
onStart: (position, event) => {
// 返回 false 可以阻止拖动
},
onMove: (position, event) => {},
onEnd: (position, event) => {},
})阻止默认行为
设置 preventDefault: true 来覆盖浏览器中某些元素(例如图片)的默认拖放行为。
ts
import { useDraggable } from '@vueuse/core'
const { x, y, style } = useDraggable(el, {
preventDefault: true,
})容器边界限制
使用 containerElement 选项将拖动限制在一个容器内。
ts
import { useDraggable } from '@vueuse/core'
const { x, y } = useDraggable(el, {
containerElement: containerRef,
})设置 autoScroll: true 以在拖动靠近边缘时启用自动滚动。
ts
const { x, y, style } = useDraggable(el, {
autoScroll: {
speed: 2, // 控制自动滚动的速度。
margin: 30, // 触发自动滚动的边缘距离。
direction: 'both' // 自动滚动的方向。
},
})组件用法
vue
<template>
<UseDraggable v-slot="{ x, y }" :initial-value="{ x: 10, y: 10 }">
拖动我!我在 {{ x }},{{ y }} 的位置
</UseDraggable>
</template>对于组件的用法,还可以传递附加属性 storageKey 和 storageType 来启用元素位置的持久化。
vue
<template>
<UseDraggable storage-key="vueuse-draggable" storage-type="session">
刷新页面后,我仍然在相同的位置!
</UseDraggable>
</template>类型声明
显示类型声明
ts
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[]>
/**
* Whether to restrict dragging within the visible area of the container.
*
* If enabled, the draggable element will not leave the visible area of its container,
* ensuring it remains within the viewport of the container during the drag.
*
* @default false
*/
restrictInView?: MaybeRefOrGetter<boolean>
/**
* Whether to enable auto-scroll when dragging near the edges.
*
* @default false
*/
autoScroll?: MaybeRefOrGetter<
| boolean
| {
/**
* Speed of auto-scroll.
*
* @default 2
*/
speed?: MaybeRefOrGetter<number | Position>
/**
* Margin from the edge to trigger auto-scroll.
*
* @default 30
*/
margin?: MaybeRefOrGetter<number | Position>
/**
* Direction of auto-scroll.
*
* @default 'both'
*/
direction?: "x" | "y" | "both"
}
>
}
export interface UseDraggableReturn {
x: Ref<number>
y: Ref<number>
position: Ref<Position>
isDragging: ComputedRef<boolean>
style: ComputedRef<string>
}
/**
* 使元素可拖动。
*
* @see https://vueuse.org/useDraggable
* @param target
* @param options
*/
export declare function useDraggable(
target: MaybeRefOrGetter<HTMLElement | SVGElement | null | undefined>,
options?: UseDraggableOptions,
): UseDraggableReturn