{"id":12457,"library":"vue-dndrop","title":"Vue Dndrop","description":"vue-dndrop is a JavaScript library providing intuitive Vue wrappers for implementing robust drag and drop functionalities within web applications. Currently at stable version 1.3.4, it offers features for reordering elements, transferring items between multiple containers, and defining custom drop rules. The library maintains a moderate release cadence, with a focus on stability and addressing common user experience issues. A key differentiator is its streamlined support for Vue 3.x, which was introduced and stabilized from versions 1.1.0/1.1.1 onwards (initially via an `@next` npm tag). This ensures seamless integration for modern Vue projects. It actively resolves challenges such as scroll blocking on touch devices during dragging and prevents errors from null container states, contributing to a more reliable and polished user experience compared to some alternative solutions.","status":"active","version":"1.3.4","language":"javascript","source_language":"en","source_url":"https://github.com/amendx/vue-dndrop","tags":["javascript","Vue","Vue.js","sortable","drag and drop","drag&drop","drag","drop","draggable"],"install":[{"cmd":"npm install vue-dndrop","lang":"bash","label":"npm"},{"cmd":"yarn add vue-dndrop","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-dndrop","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Runtime peer dependency for Vue component integration.","package":"vue","optional":false}],"imports":[{"note":"The primary component for defining a drop zone. It is a named export and should be imported directly.","wrong":"import Container from 'vue-dndrop' // Incorrect: Not a default export\nconst { Container } = require('vue-dndrop') // Incorrect: CommonJS syntax for a modern ESM-first library","symbol":"Container","correct":"import { Container } from 'vue-dndrop'"},{"note":"Used inside a `Container` to mark an element as draggable. It is a named export.","wrong":"import Draggable from 'vue-dndrop' // Incorrect: Not a default export\nconst { Draggable } = require('vue-dndrop') // Incorrect: CommonJS syntax for a modern ESM-first library","symbol":"Draggable","correct":"import { Draggable } from 'vue-dndrop'"}],"quickstart":{"code":"<template>\n  <div class=\"dnd-example\">\n    <h2>My Draggable List</h2>\n    <Container @drop=\"onDrop\" :get-child-payload=\"getChildPayload\" group-name=\"items-group\" class=\"smooth-dnd-container\">\n      <Draggable v-for=\"item in items\" :key=\"item.id\">\n        <div class=\"draggable-item\">\n          {{ item.text }}\n        </div>\n      </Draggable>\n    </Container>\n\n    <h3>Dropped Items (for demonstration)</h3>\n    <pre>{{ JSON.stringify(droppedItems, null, 2) }}</pre>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Container, Draggable } from 'vue-dndrop';\n\ninterface Item {\n  id: number;\n  text: string;\n}\n\nconst items = ref<Item[]>([\n  { id: 1, text: 'Item 1' },\n  { id: 2, text: 'Item 2' },\n  { id: 3, text: 'Item 3' }\n]);\n\nconst droppedItems = ref<Item[]>([]);\n\nconst onDrop = (dropResult: { addedIndex: number | null; removedIndex: number | null; payload: Item }) => {\n  const { addedIndex, removedIndex, payload } = dropResult;\n\n  if (removedIndex !== null && addedIndex !== null) {\n    // Reordering within the same container\n    const [removed] = items.value.splice(removedIndex, 1);\n    items.value.splice(addedIndex, 0, removed);\n  } else if (addedIndex !== null && payload) {\n    // Item was dropped into this container (e.g., from another list or a new item)\n    const newItems = [...items.value];\n    newItems.splice(addedIndex, 0, payload);\n    items.value = newItems;\n    droppedItems.value.push(payload); // Log dropped item for demo\n  }\n};\n\nconst getChildPayload = (index: number): Item => {\n  return items.value[index];\n};\n</script>\n\n<style scoped>\n.dnd-example {\n  font-family: Arial, sans-serif;\n  padding: 20px;\n  max-width: 600px;\n  margin: 0 auto;\n  border: 1px solid #eee;\n  border-radius: 8px;\n  background-color: #fff;\n}\nh2, h3 {\n  text-align: center;\n  margin-bottom: 20px;\n  color: #333;\n}\n.draggable-item {\n  padding: 15px;\n  margin-bottom: 10px;\n  background-color: #f9f9f9;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  cursor: grab;\n  box-shadow: 0 2px 4px rgba(0,0,0,0.05);\n  transition: background-color 0.2s ease;\n}\n.draggable-item:hover {\n  background-color: #f0f0f0;\n}\n.smooth-dnd-container {\n  min-height: 50px;\n  background-color: #eef;\n  padding: 10px;\n  border-radius: 4px;\n  margin-bottom: 20px;\n  border: 1px dashed #ccc;\n}\n</style>","lang":"typescript","description":"Demonstrates a basic draggable list using `vue-dndrop`'s `Container` and `Draggable` components within a Vue 3 Composition API setup. This example allows items to be reordered within a single list and logs any items successfully dropped into it, showcasing the core `onDrop` and `getChildPayload` event handlers."},"warnings":[{"fix":"Ensure you are installing `vue-dndrop` without the `@next` tag for the latest stable Vue 3 compatible version (e.g., `npm install vue-dndrop`).","message":"Vue 3.x support was initially introduced in versions 1.1.0/1.1.1 and required installing with the `@next` npm tag. While this support is now stable in main releases, users on older setups or following outdated documentation might still attempt to use `@next`. Always install the latest stable version for the best Vue 3 compatibility.","severity":"gotcha","affected_versions":"<1.1.2"},{"fix":"Upgrade to `vue-dndrop@1.3.1` or a later version to resolve the touch device scroll blocking issue and ensure a smooth user experience.","message":"Versions prior to 1.3.1 suffered from a critical bug that caused scrolling to become blocked after a drag operation, particularly on touch devices. This significantly impacted usability.","severity":"breaking","affected_versions":"<1.3.1"},{"fix":"Ensure your application is using `vue-dndrop@1.1.0` or later to benefit from improved internal handling and prevention of errors related to null container values.","message":"Older versions (specifically prior to 1.1.0, and 1.0.3 addressing some aspects) lacked robust error prevention when `Container` components unexpectedly received `null` values, potentially leading to runtime errors.","severity":"gotcha","affected_versions":"<1.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Update `vue-dndrop` to version 1.3.1 or newer. Use `npm update vue-dndrop` or `npm install vue-dndrop@latest`.","cause":"A known bug in `vue-dndrop` versions prior to 1.3.1 affecting how touch events and scroll locks were handled.","error":"Scrolling is blocked on touch devices after completing a drag operation."},{"fix":"Upgrade `vue-dndrop` to version 1.1.0 or newer. This version includes fixes for preventing errors when containers receive null values. Use `npm install vue-dndrop@latest`.","cause":"A `Container` component received a `null` value in an older version of the library, which was not gracefully handled, leading to unhandled exceptions.","error":"TypeError: Cannot read properties of null (reading 'value') or similar errors originating from a `Container` component."},{"fix":"Verify that your `getChildPayload` function always returns a valid object for every accessible index. In your `onDrop` handler, implement checks to ensure `payload` is not `undefined` or `null` before attempting to access its properties. Consult the updated documentation (from v1.3.1 onwards) for the correct usage of `getChildPayload` and the `dropResult` structure.","cause":"The `getChildPayload` function might not be returning a valid object for the given index, or the `payload` property within the `dropResult` object is `undefined` (e.g., a drag operation was cancelled or initiated from an invalid source). Additionally, documentation for `getChildPayload` had incorrect links in older versions.","error":"TypeError: Cannot read properties of undefined (reading 'payload') in `onDrop` handlers or similar issues related to payload data."}],"ecosystem":"npm"}