Nuxt module for typed-vuedraggable - Vue.js draggable component with full TypeScript support powered by Sortable.js.
- 🚀 Full TypeScript support - Complete type definitions for all props and events
- 🎨 Auto-import - Components are automatically available in your templates
- 📦 Small bundle - Only includes what you need
- 🔄 Two-way binding - Works with
v-modelfor seamless data synchronization - 🎯 Slot-based API - Flexible item rendering with header and footer slots
- 🔀 Multi-list support - Drag and drop between multiple lists
- 🎬 Transition support - Works with Vue transitions out of the box
Install the module to your Nuxt application with one command:
npx nuxi module add @typed-draggable/nuxtOr install manually:
# npm
npm install @typed-draggable/nuxt
# pnpm
pnpm add @typed-draggable/nuxt
# yarn
yarn add @typed-draggable/nuxtThen add the module to your nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@typed-draggable/nuxt'],
draggable: {
// module options
prefix: '', // optional prefix for component name
},
})That's it! You can now use the Draggable component in your Nuxt app ✨
<template>
<Draggable v-model="items" item-key="id" ghost-class="ghost">
<template #item="{ element }">
<div class="item">{{ element.name }}</div>
</template>
</Draggable>
</template>
<script setup lang="ts">
interface Item {
id: number
name: string
}
const items = ref<Item[]>([
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
])
</script><template>
<div class="lists">
<Draggable v-model="listA" item-key="id" group="shared">
<template #item="{ element }">
<div class="item">{{ element.name }}</div>
</template>
</Draggable>
<Draggable v-model="listB" item-key="id" group="shared">
<template #item="{ element }">
<div class="item">{{ element.name }}</div>
</template>
</Draggable>
</div>
</template><template>
<Draggable v-model="items" item-key="id">
<template #header>
<div class="header">Header - Not draggable</div>
</template>
<template #item="{ element, index }">
<div class="item">{{ index + 1 }}. {{ element.name }}</div>
</template>
<template #footer>
<div class="footer">Footer - Not draggable</div>
</template>
</Draggable>
</template><template>
<Draggable v-model="items" item-key="id" tag="ul">
<template #item="{ element }">
<li>{{ element.name }}</li>
</template>
</Draggable>
</template><template>
<Draggable v-model="items" item-key="id" tag="TransitionGroup" :component-data="{ name: 'list' }">
<template #item="{ element }">
<div class="item">{{ element.name }}</div>
</template>
</Draggable>
</template>
<style>
.list-move {
transition: transform 0.3s;
}
</style>| Prop | Type | Default | Description |
|---|---|---|---|
v-model / modelValue |
T[] |
null |
The list of items (two-way bound) |
list |
T[] |
null |
Alternative to v-model (one-way) |
itemKey |
string | ((item: T) => string | number) |
required | Unique key for each item |
tag |
string |
'div' |
HTML tag or component name for the container |
clone |
(item: T) => T |
(x) => x |
Function to clone items |
move |
(evt, originalEvent) => boolean | void |
null |
Function to determine if move is allowed |
componentData |
object |
null |
Props to pass to the container component |
All Sortable.js options are also supported as props (e.g., group, sort, delay, animation, handle, ghostClass, etc.).
| Event | Payload | Description |
|---|---|---|
update:modelValue |
T[] |
Emitted when the list changes |
change |
ChangeEvent<T> |
Emitted on add, remove, or move with details |
start |
SortableEvent |
Drag started |
end |
SortableEvent |
Drag ended |
add |
SortableEvent |
Item added to list |
remove |
SortableEvent |
Item removed from list |
update |
SortableEvent |
Item moved within list |
choose |
SortableEvent |
Item chosen |
unchoose |
SortableEvent |
Item unchosen |
sort |
SortableEvent |
Sorting changed |
filter |
SortableEvent |
Tried to drag filtered item |
clone |
SortableEvent |
Clone created |
The module provides full TypeScript support. Import types as needed:
import type {
ChangeEvent,
AddedEvent,
RemovedEvent,
MovedEvent,
MoveEventContext
} from '@typed-draggable/nuxt/runtime/types'
function handleChange(event: ChangeEvent<MyItem>) {
if ('added' in event) {
console.log('Added:', event.added.element)
}
}- The component only works on the client side (uses
SortableJSwhich requires DOM) - Wrap in
<ClientOnly>if needed for SSR applications itemKeyprop is required and must return unique values for each item
# Install dependencies
pnpm install
# Generate type stubs
pnpm run dev:prepare
# Develop with the playground
pnpm run dev
# Build the module
pnpm run prepack
# Run tests
pnpm run test