{"id":15048,"library":"vuedraggable-es","title":"Vue Draggable ES","description":"vuedraggable-es is a Vue.js 3 component that enables drag-and-drop functionality for lists, keeping the view model array synchronized with the HTML. It is built upon and exposes all features of Sortable.js, including touch device support, drag handles, smart auto-scrolling, and inter-list dragging. The current stable version is 4.1.1, and it is actively maintained with frequent bug fixes and feature enhancements, as seen in the recent release history. A key differentiator is its explicit compatibility with Vue 3's `transition-group` component and its focus on being an ES module, making it suitable for modern Vue projects. It also allows making existing UI library components draggable while maintaining full control via events. Its development follows the `vue.draggable.next` project, targeting Vue 3 exclusively.","status":"active","version":"4.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/SortableJS/Vue.Draggable","tags":["javascript","vue","vuejs","drag","and","drop","list","Sortable.js","component","typescript"],"install":[{"cmd":"npm install vuedraggable-es","lang":"bash","label":"npm"},{"cmd":"yarn add vuedraggable-es","lang":"bash","label":"yarn"},{"cmd":"pnpm add vuedraggable-es","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Runtime dependency for Vue 3 applications, as `vuedraggable-es` is built for Vue 3.","package":"vue","optional":false}],"imports":[{"note":"This package (`vuedraggable-es`) is an ES module and exports the `draggable` component as its default export. While some documentation or older examples might show `import draggable from 'vuedraggable'`, the correct import path for the `vuedraggable-es` package is `vuedraggable-es`.","wrong":"const draggable = require('vuedraggable-es')","symbol":"draggable","correct":"import draggable from 'vuedraggable-es'"},{"note":"TypeScript type definitions are available for the component's props, events, and other related types, enhancing developer experience in TypeScript projects.","symbol":"DraggableComponent","correct":"import type { DraggableComponent, DraggableEvents } from 'vuedraggable-es'"},{"note":"For direct browser usage via CDN, the `VueDraggable` global is exposed. Note that the CDN example often references an older `vuedraggable` package version (e.g., 4.0.0), which may differ from the latest `vuedraggable-es` npm package behavior. Verify compatibility for your specific use case.","symbol":"VueDraggable (UMD)","correct":"<script src=\"//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/4.0.0/vuedraggable.umd.min.js\"></script>"}],"quickstart":{"code":"<script setup>\nimport draggable from 'vuedraggable-es'\nimport { ref } from 'vue'\n\nconst myArray = ref([\n  { id: 1, name: 'Item 1' },\n  { id: 2, name: 'Item 2' },\n  { id: 3, name: 'Item 3' },\n]);\nconst drag = ref(false);\n\nfunction handleStart() {\n  drag.value = true;\n  console.log('Drag started');\n}\n\nfunction handleEnd() {\n  drag.value = false;\n  console.log('Drag ended', myArray.value);\n}\n</script>\n\n<template>\n  <div style=\"font-family: sans-serif; padding: 20px;\">\n    <h2>Draggable List</h2>\n    <p>Drag status: {{ drag ? 'Dragging' : 'Not dragging' }}</p>\n    <draggable\n      v-model=\"myArray\"\n      group=\"people\"\n      @start=\"handleStart\"\n      @end=\"handleEnd\"\n      item-key=\"id\"\n      style=\"border: 1px solid #ccc; padding: 10px; min-height: 50px;\"\n    >\n      <template #item=\"{ element }\">\n        <div style=\"background: #f9f9f9; border: 1px solid #eee; margin-bottom: 5px; padding: 8px; cursor: grab;\">\n          {{ element.name }}\n        </div>\n      </template>\n    </draggable>\n    <pre style=\"background: #eee; padding: 10px; margin-top: 20px;\">{{ JSON.stringify(myArray, null, 2) }}</pre>\n  </div>\n</template>","lang":"typescript","description":"Demonstrates a basic draggable list using `vuedraggable-es` with Vue 3's Composition API, `v-model` for synchronization, and event handling for drag start/end states in a single file component."},"warnings":[{"fix":"For Vue 2 projects, you must use the `vuedraggable` package (without the `-es` suffix). For Vue 3 projects, ensure your `vue` peer dependency is `^3.2.31` or higher for `vuedraggable-es`.","tags":["vue2","vue3","compatibility"],"message":"This package, `vuedraggable-es`, is specifically designed for Vue 3 and is incompatible with Vue 2 or earlier versions. Attempting to use it in a Vue 2 project will result in runtime errors related to Vue's internal APIs.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Always provide a unique `item-key` prop that points to a stable identifier on your list items, e.g., `:item-key=\"'id'\"` or `:item-key=\"element => element.uniqueId\"`.","tags":["vue3","item-key","reactivity"],"message":"When using `vuedraggable-es` with Vue 3, the `item-key` prop is mandatory. This prop is crucial for Vue's reactivity system to track elements efficiently, especially when reordering or using `transition-group`.","severity":"gotcha","affected_versions":">=4.0.0"},{"fix":"Ensure your structure follows the pattern: `<draggable v-model=\"myArray\" tag=\"transition-group\" item-key=\"id\"><template #item=\"{element}\"><div>{{element.name}}</div></template></draggable>`.","tags":["transition-group","slots","vue3"],"message":"The usage of `transition-group` with `vuedraggable-es` requires a specific structure. The `transition-group` component should be effectively 'aliased' by passing `tag=\"transition-group\"` to the `draggable` component, and then the list items are rendered via the `#item` slot.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Always use `import draggable from 'vuedraggable-es'` and ensure your build setup (Vite, Webpack, Rollup) is configured to handle ES modules correctly. If you encounter issues, verify your `package.json` `type` field is set to `module` or that your bundler explicitly handles ESM.","tags":["esm","cjs","module","imports"],"message":"The `vuedraggable-es` package is an ES module (ESM) and is not intended for direct use with CommonJS `require()` statements or in environments that do not support ESM. This is reflected in its package name suffix `-es`.","severity":"gotcha","affected_versions":">=4.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure `import draggable from 'vuedraggable-es'` is present in your script and that `draggable` is registered in your component's `components` option or globally if not using `<script setup>`.","cause":"The `draggable` component was not correctly imported or registered in your Vue application.","error":"[Vue warn]: Failed to resolve component: draggable"},{"fix":"Add the `item-key` prop to the `<draggable>` component, e.g., `:item-key=\"'id'\"`, pointing to a unique identifier property within your list items.","cause":"This TypeScript error indicates that the mandatory `item-key` prop for `vuedraggable-es` in Vue 3 is missing.","error":"Property 'item-key' is missing in type '{ ... }' but required in type '{ itemKey: any; }'."},{"fix":"If your project is Vue 2, you must uninstall `vuedraggable-es` and install the `vuedraggable` package. If your project is Vue 3, ensure your `vue` package version meets the `vuedraggable-es` peer dependency requirements (e.g., `^3.2.31`).","cause":"You are attempting to use `vuedraggable-es` (designed for Vue 3) within a Vue 2 project, leading to incompatibility with Vue 3-specific APIs.","error":"Uncaught TypeError: vue.defineComponent is not a function"}],"ecosystem":"npm"}