Docs/Getting started

Quick start

A sortable list in three files — a provider, a list and its rows.

Here is the whole thing, running. Drag a row, or Tab to one, press Space, move it with the arrow keys and press Space again.

Live

Loading the demo…

<script setup lang="ts">
import { DnDProvider } from '@vue-dnd-kit/core';
import TaskList from './TaskList.vue';
</script>

<template>
  <!-- The provider goes around the components that drag (often the whole app). -->
  <DnDProvider>
    <TaskList />
  </DnDProvider>
</template>

Step by step

Wrap the app in a provider

DnDProvider owns the drag. Every composable must run in a component rendered inside it — not in the component whose template contains it.

Make a list

makeSortableList takes the list's element and your array. It returns items: a draft that reorders live while you drag. Render the draft, not your array, and key the rows by id.

Make the rows

Each row calls makeSortableItem with its element and the item it renders. Its key comes from item.id.

When the drop lands, tasks gets the new order — it's a regular ref, so the rest of your app sees the change like any other.

Using Pinia, a server or immutable data? Pass a getter instead of a ref, then call e.preventDefault() in onDrop and apply e.result yourself.