packages/core/useDraggable/index.md
Make elements draggable.
<script setup lang="ts">
import { useDraggable } from '@vueuse/core'
import { useTemplateRef } from 'vue'
const el = useTemplateRef('el')
// `style` will be a helper computed for `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">
Drag me! I am at {{ x }}, {{ y }}
</div>
</template>
| Property | Type | Description |
|---|---|---|
x | Ref<number> | Current x position |
y | Ref<number> | Current y position |
position | Ref<{x, y}> | Current position object |
isDragging | ComputedRef<boolean> | Whether currently dragging |
style | ComputedRef<string> | CSS style string left: ?px; top: ?px; |
useDraggable(el, {
// Initial position (default: { x: 0, y: 0 })
initialValue: { x: 40, y: 40 },
// Restrict dragging to specific axis: 'x', 'y', or 'both' (default)
axis: 'both',
// Only trigger when clicking directly on the element (default: false)
exact: false,
// Prevent default browser behavior (default: false)
preventDefault: true,
// Stop event propagation (default: false)
stopPropagation: false,
// Use capture phase for events (default: true)
capture: true,
// Disable dragging (default: false)
disabled: false,
// Mouse buttons that trigger drag (default: [0] - left button)
buttons: [0],
// Pointer types to listen to (default: ['mouse', 'touch', 'pen'])
pointerTypes: ['mouse', 'touch', 'pen'],
// Custom drag handle element (default: target element)
handle: handleRef,
// Container element for bounds (default: none)
containerElement: containerRef,
// Element to attach pointermove/pointerup events (default: window)
draggingElement: window,
// Callbacks
onStart: (position, event) => {
// Return false to prevent dragging
},
onMove: (position, event) => {},
onEnd: (position, event) => {},
})
Set preventDefault: true to override the default drag-and-drop behavior of certain elements in the browser (e.g., images).
import { useDraggable } from '@vueuse/core'
const { x, y, style } = useDraggable(el, {
preventDefault: true,
})
Use containerElement to constrain dragging within a container.
import { useDraggable } from '@vueuse/core'
const { x, y } = useDraggable(el, {
containerElement: containerRef,
})
Set autoScroll: true to enable auto-scroll when dragging near the edges.
const { x, y, style } = useDraggable(el, {
autoScroll: {
speed: 2, // Control the speed of auto-scroll.
margin: 30, // Set the margin from the edge that triggers auto-scroll.
direction: 'both' // Determine the direction of auto-scroll.
},
})
<template>
<UseDraggable v-slot="{ x, y }" :initial-value="{ x: 10, y: 10 }">
Drag me! I am at {{ x }}, {{ y }}
</UseDraggable>
</template>
For component usage, additional props storageKey and storageType can be passed to the component and enable the persistence of the element position.
<template>
<UseDraggable storage-key="vueuse-draggable" storage-type="session">
Refresh the page and I am still in the same position!
</UseDraggable>
</template>