Composables

useDraggable

Make elements draggable with the useDraggable composable.

Usage

The useDraggable composable requires a unique id and an element template ref. It returns reactive computed properties for the drag state.

<script setup>
import {ref} from 'vue';
import {useDraggable} from '@dnd-kit/vue';

const element = ref(null);
const {isDragging} = useDraggable({id: 'my-draggable', element});
</script>

<template>
  <button ref="element" :data-dragging="isDragging">
    Drag me
  </button>
</template>

Input

All input properties accept plain values or Vue refs/getters (MaybeRefOrGetter), so they can be reactive.

id
MaybeRefOrGetter<UniqueIdentifier>
required

A unique identifier for this draggable instance.

element
MaybeRefOrGetter<HTMLElement | null>
required

A template ref pointing to the draggable element.

handle
MaybeRefOrGetter<HTMLElement | null>

A template ref for a drag handle. When set, only this element activates dragging.

disabled
MaybeRefOrGetter<boolean>

Whether the draggable is disabled.

plugins
MaybeRefOrGetter<PluginDescriptor[]>

An array of plugin descriptors for per-entity plugin configuration. Use Plugin.configure() to create descriptors. For example, Feedback.configure({ feedback: 'clone' }).

modifiers
MaybeRefOrGetter<Modifier[]>

Modifiers to apply to this draggable instance.

sensors
MaybeRefOrGetter<Sensor[]>

Sensors to use for this draggable instance.

data
MaybeRefOrGetter<Data>

Custom data to attach to this draggable instance.

Output

isDragging
ComputedRef<boolean>

Whether this element is currently being dragged (visually).

isDropping
ComputedRef<boolean>

Whether this element is in the process of being dropped (animating to final position).

isDragSource
ComputedRef<boolean>

Whether this element is the source of the current drag operation.

draggable
ShallowReadonly<Ref<Draggable>>

The underlying Draggable instance.

Guides

Rendering a drag overlay

You can render a completely different element while the draggable element is being dragged by using the <DragOverlay> component.

<script setup>
import {ref} from 'vue';
import {DragDropProvider, DragOverlay, useDraggable} from '@dnd-kit/vue';

const element = ref(null);
useDraggable({id: 'draggable', element});
</script>

<template>
  <DragDropProvider>
    <button ref="element">Draggable</button>
    <DragOverlay>
      <div>I will be rendered while dragging...</div>
    </DragOverlay>
  </DragDropProvider>
</template>

The <DragOverlay> component will only render its children when a drag operation is in progress. This can be useful for rendering a completely different element while the draggable element is being dragged.

You should only render the <DragOverlay> component once per DragDropProvider.

To render different content depending on which element is being dragged, use the scoped slot to access the drag source:

<script setup>
import {DragDropProvider, DragOverlay} from '@dnd-kit/vue';
</script>

<template>
  <DragDropProvider>
    <Draggable id="foo" />
    <Draggable id="bar" />
    <DragOverlay>
      <template #default="{ source }">
        <div>Dragging {{ source.id }}</div>
      </template>
    </DragOverlay>
  </DragDropProvider>
</template>