{"id":12632,"library":"vue3-smooth-dnd","title":"Vue 3 Smooth Drag and Drop","description":"vue3-smooth-dnd is a specialized Vue 3 wrapper for the highly performant `smooth-dnd` library, providing components for intuitive drag-and-drop functionality within Vue applications. Currently at version 0.0.6, the package primarily focuses on maintaining compatibility with the underlying `smooth-dnd` library and fixing integration-specific bugs. While release cadence is not formally established, updates appear to be driven by reported issues. Its key differentiator lies in directly porting the well-regarded Vue 2 `vue-smooth-dnd` wrapper to the Vue 3 ecosystem, aiming for a seamless transition for developers familiar with the original. It offers a robust, highly customizable, and visually smooth solution for list reordering and item movement, distinguishing itself from simpler drag-and-drop solutions by leveraging `smooth-dnd`'s optimized animation and physics.","status":"active","version":"0.0.6","language":"javascript","source_language":"en","source_url":"https://github.com/gilnd/vue3-smooth-dnd","tags":["javascript","Vue 3","Vue next","Vue","Vue.js","sortable","drag and drop","drag&drop","drag"],"install":[{"cmd":"npm install vue3-smooth-dnd","lang":"bash","label":"npm"},{"cmd":"yarn add vue3-smooth-dnd","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue3-smooth-dnd","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for Vue 3 application integration.","package":"vue","optional":false}],"imports":[{"note":"This library is designed for ESM environments typical of modern Vue 3 projects. CommonJS `require` syntax is not supported for direct module import.","wrong":"const { Container } = require('vue3-smooth-dnd')","symbol":"Container","correct":"import { Container } from 'vue3-smooth-dnd'"},{"note":"Both `Container` and `Draggable` are named exports. Attempting a default import will result in an undefined module error.","wrong":"import Draggable from 'vue3-smooth-dnd'","symbol":"Draggable","correct":"import { Draggable } from 'vue3-smooth-dnd'"},{"note":"While `import * as DndComponents` might work, it's generally recommended to destructure specific named exports for better tree-shaking and clarity.","wrong":"import * as DndComponents from 'vue3-smooth-dnd'","symbol":"Container, Draggable","correct":"import { Container, Draggable } from 'vue3-smooth-dnd'"}],"quickstart":{"code":"<template>\n  <div>\n    <span>Studio Ghibli Tier List</span>\n    <Container @drop=\"onDrop\">            \n      <Draggable v-for=\"(item, i) in items\" :key=\"item.id\">\n        <div>\n           {{i + 1}} -> {{item.data}}\n        </div>\n      </Draggable>\n    </Container>\n  </div>\n</template>\n\n<script>\nimport { Container, Draggable } from \"vue3-smooth-dnd\";\nexport default {\n  name: \"app\",\n  components: { Container, Draggable },\n  data() {\n    return {\n      items: [\n        { id: 1, data: \"Princess Mononoke\" },\n        { id: 2, data: \"Spirited Away\" },\n        { id: 3, data: \"My Neighbor Totoro\" },\n        { id: 4, data: \"Howl's Moving Castle\" }\n      ]\n    };\n  },\n  methods: {  \n    onDrop(dropResult){\n      this.items = this.applyDrag(this.items, dropResult);\n    },\n    applyDrag(arr, dragResult){\n      const { removedIndex, addedIndex, payload } = dragResult;\n\n      if (removedIndex === null && addedIndex === null) return arr;\n      const result = [...arr];\n      let itemToAdd = payload;\n      \n      if (removedIndex !== null) {\n        itemToAdd = result.splice(removedIndex, 1)[0];\n      }\n      if (addedIndex !== null) {\n        result.splice(addedIndex, 0, itemToAdd);\n      }\n      return result;\n    }\n  }\n}\n</script>\n","lang":"javascript","description":"This example demonstrates how to set up a basic draggable list, render items using `Draggable` components within a `Container`, and handle drag-and-drop events to update the list's order."},"warnings":[{"fix":"Refer to official Vue 3 documentation and adapt Vue 2 examples to Vue 3's best practices, especially concerning reactivity, component lifecycle, and global instance configuration.","message":"The documentation states that 'All the documentation for the Vue 2 version works with this package version too!' While the core logic of `smooth-dnd` might be consistent, Vue 3 introduces significant changes (e.g., Composition API, global mounting, `v-model` behavior). Developers should be cautious when directly applying Vue 2 code patterns from the original wrapper's documentation without validating Vue 3 compatibility.","severity":"gotcha","affected_versions":">=0.0.2"},{"fix":"Use exact version pinning in `package.json` (e.g., `\"vue3-smooth-dnd\": \"0.0.6\"`) and review changelogs carefully before upgrading.","message":"As a `0.0.x` version, the package API, while based on a stable Vue 2 predecessor, could still introduce minor breaking changes or unexpected behaviors in future patch or minor releases. Developers should pin to exact versions and thoroughly test updates.","severity":"breaking","affected_versions":">=0.0.2"},{"fix":"Ensure that `v-for` keys are stable and unique. When modifying the underlying data array (`items` in the quickstart), always create a new array instance or use Vue's reactivity methods (e.g., `this.$set` in Options API or `Vue.set` for older Vue 2, though direct array manipulation is usually reactive in Vue 3 if a new array is assigned) to trigger proper updates.","message":"Interactions between `smooth-dnd`'s internal DOM manipulation and Vue's reactivity system can sometimes lead to unexpected issues if not handled correctly, especially when dynamically adding/removing items or complex nested structures. This can manifest as visual glitches or incorrect drag behavior.","severity":"gotcha","affected_versions":">=0.0.2"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"This issue was specifically addressed in `v0.0.6`. Ensure you are on the latest patch version. If it persists, it may indicate a specific edge case in your component's lifecycle or complex nested drag-and-drop scenarios that need careful management of component unmounting and re-rendering.","cause":"An internal reference within `smooth-dnd` or its Vue wrapper became null, possibly due to a race condition or an unmounted component during a drag operation.","error":"TypeError: Cannot read properties of null (reading 'cancelDrop')"},{"fix":"Ensure `import { Container, Draggable } from \"vue3-smooth-dnd\";` is present in your script and that `components: { Container, Draggable }` is correctly declared in your Vue component options.","cause":"The `Container` or `Draggable` components were not properly registered or imported into the Vue component where they are being used.","error":"[Vue warn]: Failed to resolve component: container / [Vue warn]: Failed to resolve component: draggable"}],"ecosystem":"npm"}