{"id":12462,"library":"vue-draggable-plus","title":"Vue Draggable Plus","description":"Vue Draggable Plus is a universal drag-and-drop component library supporting both Vue 3 and Vue 2.7+ applications, building upon the capabilities of Sortablejs. The current stable version is 0.6.1, with an active release cadence reflecting ongoing development and maintenance. It addresses a gap where the official Sortablejs Vue components had become out of sync with modern Vue 3 practices. A key differentiator is its flexibility, offering multiple usage patterns including a component, a Composition API composable (`useDraggable`), and a directive (`v-draggable`). It uniquely solves the problem of integrating drag-and-drop with complex component libraries by allowing developers to specify any element as the drag container using a selector, overcoming limitations of previous implementations that required the component itself to be the direct list child. The library ships with comprehensive TypeScript types.","status":"active","version":"0.6.1","language":"javascript","source_language":"en","source_url":"https://github.com/Alfred-Skyblue/vue-draggable-plus","tags":["javascript","vue","vue2.x","vue3.x","Sortable","sortablejs","drag","dragging","vue-draggable","typescript"],"install":[{"cmd":"npm install vue-draggable-plus","lang":"bash","label":"npm"},{"cmd":"yarn add vue-draggable-plus","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-draggable-plus","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency for TypeScript definitions when working with Sortablejs options.","package":"@types/sortablejs","optional":true},{"reason":"Underlying drag-and-drop library. While not a direct peer dependency in package.json, it's the core engine this library wraps.","package":"sortablejs","optional":false}],"imports":[{"note":"Primary component for declarative drag-and-drop usage. This package is ESM-first, CJS `require` is generally discouraged.","wrong":"const VueDraggable = require('vue-draggable-plus').VueDraggable","symbol":"VueDraggable","correct":"import { VueDraggable } from 'vue-draggable-plus'"},{"note":"Composition API composable for programmatic drag-and-drop control. Commonly misused as a default import.","wrong":"import VueDraggable from 'vue-draggable-plus'","symbol":"useDraggable","correct":"import { useDraggable } from 'vue-draggable-plus'"},{"note":"Directive for concise drag-and-drop functionality directly on an element. The directive name starts with 'v' and uses named export.","wrong":"import { Draggable } from 'vue-draggable-plus'","symbol":"vDraggable","correct":"import { vDraggable } from 'vue-draggable-plus'"},{"note":"While `vue-draggable-plus` exposes some types, for core Sortablejs event types, directly importing from `sortablejs` is the standard and often more reliable approach.","wrong":"import type { SortableEvent } from 'vue-draggable-plus'","symbol":"SortableEvent","correct":"import type { SortableEvent } from 'sortablejs'"}],"quickstart":{"code":"```typescript\n<template>\n  <div ref=\"el\" class=\"drag-container\">\n    <div v-for=\"item in list\" :key=\"item.id\" class=\"drag-item\">\n      {{ item.name }}\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue'\nimport { useDraggable } from 'vue-draggable-plus'\n\ninterface ListItem {\n  name: string;\n  id: number;\n}\n\nconst el = ref<HTMLElement | null>(null)\nconst list = ref<ListItem[]>([\n  { name: 'Item A', id: 1 },\n  { name: 'Item B', id: 2 },\n  { name: 'Item C', id: 3 },\n  { name: 'Item D', id: 4 }\n])\n\nconst draggable = useDraggable(el, list, {\n  animation: 150,\n  onStart() {\n    console.log('Drag started')\n  },\n  onEnd(event) {\n    console.log('Drag ended:', event.oldIndex, '->', event.newIndex)\n    // The list.value is automatically updated by useDraggable\n  }\n})\n\nonMounted(() => {\n  // For demonstration, you could programmatically start/destroy draggable if needed\n  // console.log('Draggable instance:', draggable)\n})\n</script>\n\n<style>\n.drag-container {\n  border: 1px solid #eee;\n  padding: 10px;\n  min-height: 100px;\n}\n.drag-item {\n  padding: 8px 12px;\n  margin-bottom: 5px;\n  background-color: #f9f9f9;\n  border: 1px solid #ddd;\n  cursor: grab;\n}\n.drag-item:hover {\n  background-color: #f0f0f0;\n}\n</style>\n```","lang":"typescript","description":"This quickstart demonstrates how to set up a basic draggable list using the `useDraggable` Composition API composable, binding it to a `ref` element and a reactive array. It includes basic styling and logs drag events."},"warnings":[{"fix":"Upgrade `vue-draggable-plus` to version `0.5.0` or newer to ensure `v-model` reactivity for add/remove operations.","message":"Prior to version 0.5.0, the `v-model` (which uses `update:model-value`) might not have correctly triggered updates when items were added or removed from the draggable list, potentially leading to out-of-sync data in your application state.","severity":"gotcha","affected_versions":"<0.5.0"},{"fix":"Update `vue-draggable-plus` to version `0.4.1` or later. For `SortableEvent` specifically, consider importing `SortableEvent` directly from `sortablejs` for robustness if issues persist.","message":"In TypeScript projects, obtaining correct types for `Sortablejs` options (e.g., `Options`) and events (e.g., `SortableEvent`) directly from `vue-draggable-plus` was problematic in older versions, leading to type errors or needing workarounds.","severity":"gotcha","affected_versions":"<0.4.1"},{"fix":"Upgrade `vue-draggable-plus` to version `0.5.3` or newer to restore the intended functionality of the `onMove` callback for preventing drag actions.","message":"The `onMove` callback, which allows you to prevent dragging of specific items by returning `false`, did not function correctly in versions prior to 0.5.3, meaning it was impossible to programmatically stop a drag action.","severity":"gotcha","affected_versions":"<0.5.3"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Upgrade `vue-draggable-plus` to version `0.4.1` or newer. For `SortableEvent` and other core Sortablejs types, import them directly from `sortablejs` (e.g., `import type { SortableEvent } from 'sortablejs';`).","cause":"Attempting to import or use TypeScript types (like `Options` or `SortableEvent`) directly from `vue-draggable-plus` in versions prior to 0.4.1, where they were not correctly exported or defined.","error":"Property 'Options' does not exist on type 'typeof import(\"vue-draggable-plus\")'."},{"fix":"Update `vue-draggable-plus` to version `0.5.0` or newer. If stuck on an older version, manually update your data array based on the `onAdd` or `onRemove` events.","cause":"A bug in `vue-draggable-plus` versions prior to 0.5.0 prevented the `update:model-value` event from firing correctly when items were added or removed, only handling reordering.","error":"Data does not update when adding or removing items from a `v-model` bound list after a drag operation."},{"fix":"Upgrade `vue-draggable-plus` to version `0.5.3` or newer.","cause":"A defect in `vue-draggable-plus` versions prior to 0.5.3 caused the return value of the `onMove` callback to be ignored, failing to prevent the element from being dragged.","error":"The `onMove` callback function is not preventing items from being dragged, even when it returns `false`."}],"ecosystem":"npm"}