{"id":18078,"library":"vue-nestable","title":"Vue Nestable","description":"vue-nestable is a Vue component designed for creating drag-and-drop hierarchical lists, commonly known as tree views. It allows users to reorder items and intuitively nest them by dragging horizontally. As of version 2.6.0, this package is compatible only with Vue 2 applications. A key differentiator is its deliberate lack of built-in CSS, providing developers with complete control over styling. It offers extensive customization through props for specifying the item identifier (`keyProp`), maximum nesting depth (`maxDepth`), and the horizontal threshold (`threshold`) for nesting actions. The library emphasizes a lightweight and flexible approach, requiring developers to manage their own item data structures and providing components like `VueNestable` for the list and `VueNestableHandle` for draggable areas.","status":"active","version":"2.6.0","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","vue","vue-nestable","vue nestable","vue tree"],"install":[{"cmd":"npm install vue-nestable","lang":"bash","label":"npm"},{"cmd":"yarn add vue-nestable","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-nestable","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"For global registration as a Vue plugin. This pattern is typical for Vue 2 plugins. Vue 3 has a different global registration approach.","wrong":"const VueNestable = require('vue-nestable');","symbol":"VueNestable (global)","correct":"import VueNestable from 'vue-nestable';\nVue.use(VueNestable);"},{"note":"For on-demand, local component registration. Requires named import.","wrong":"import VueNestable from 'vue-nestable'; // Incorrect for named export\nconst VueNestable = require('vue-nestable').VueNestable;","symbol":"VueNestable (component)","correct":"import { VueNestable } from 'vue-nestable';"},{"note":"Used to designate the draggable area within a list item. Always imported as a named export.","wrong":"import VueNestableHandle from 'vue-nestable'; // Incorrect for named export","symbol":"VueNestableHandle","correct":"import { VueNestableHandle } from 'vue-nestable';"}],"quickstart":{"code":"<template>\n  <div id=\"app\">\n    <h1>My Nestable List</h1>\n    <vue-nestable v-model=\"nestableItems\" :maxDepth=\"3\">\n      <vue-nestable-handle\n        slot-scope=\"{ item }\"\n        :item=\"item\"\n        :key=\"item.id\"\n        class=\"nestable-item\"\n      >\n        {{ item.text }} (ID: {{ item.id }})\n      </vue-nestable-handle>\n    </vue-nestable>\n    <pre>{{ JSON.stringify(nestableItems, null, 2) }}</pre>\n  </div>\n</template>\n\n<script>\nimport Vue from 'vue';\nimport { VueNestable, VueNestableHandle } from 'vue-nestable';\n\nVue.component('VueNestable', VueNestable);\nVue.component('VueNestableHandle', VueNestableHandle);\n\nexport default {\n  name: 'App',\n  data() {\n    return {\n      nestableItems: [\n        { id: 0, text: 'Task Alpha' },\n        { id: 1, text: 'Task Beta', children: [{ id: 2, text: 'Subtask Gamma' }] },\n        { id: 3, text: 'Task Delta' },\n        { id: 4, text: 'Task Epsilon', children: [{ id: 5, text: 'Subtask Zeta' }] }\n      ]\n    };\n  }\n};\n</script>\n\n<style>\n/* Basic styling for demo purposes */\n.nestable-item {\n  padding: 10px;\n  margin: 5px 0;\n  border: 1px solid #ddd;\n  background: #f9f9f9;\n  cursor: grab;\n}\n.nestable-item:active {\n  cursor: grabbing;\n}\n</style>","lang":"javascript","description":"This quickstart demonstrates how to set up a basic draggable and nestable list using `vue-nestable` components, including local registration and initial data. It also includes minimal styling and displays the updated data model."},"warnings":[{"fix":"For new Vue 3 projects, use a Vue 3-compatible alternative like `vue3-nestable`. For existing Vue 2 projects, ensure your Vue version is 2.x. If migrating a Vue 2 app to Vue 3 with this dependency, you might need to find a Vue 3 port or replace the component.","message":"This `vue-nestable` package (rhwilr/vue-nestable) is explicitly compatible only with Vue 2. It does not support Vue 3, and there are no current plans for official Vue 3 compatibility from this specific maintainer. For Vue 3, consider alternative packages like `vue3-nestable` (fbki/vue3-nestable or stepanenko3/vue3-nestable) or migrate your application using `@vue/compat` if feasible.","severity":"breaking","affected_versions":">=2.x"},{"fix":"Ensure all items have a unique `id` (or `keyProp`) property. Sanitize `id` values to only include characters valid for CSS class names (alphanumeric, hyphens, underscores) if they originate from external sources.","message":"Each item provided to the `vue-nestable` component via `v-model` or the `value` prop *must* have a unique `id` property (or a custom `keyProp` value). Furthermore, this `id` must be a valid CSS class name, meaning it cannot contain special characters like `:`, `,`, `.`, or `;`.","severity":"gotcha","affected_versions":">=2.x"},{"fix":"Implement custom CSS for the `vue-nestable` and `vue-nestable-handle` components to define their appearance, padding, margins, drag styles, and nesting indentation. The demo's CSS can serve as a starting point.","message":"The `vue-nestable` component ships without any default styling. While this offers full customization flexibility, developers must provide their own CSS to make the list visually functional and appealing.","severity":"gotcha","affected_versions":">=2.x"},{"fix":"Always bind `:item=\"item\"` and provide a unique `:key=\"item.id\"` (or corresponding `keyProp`) to `vue-nestable-handle` within your `slot-scope` template.","message":"When using `slot-scope` for custom item rendering, ensure the `item` prop is correctly bound to `vue-nestable-handle` and a unique `:key` is provided for each item for optimal Vue reactivity and performance. Omitting the `:key` can lead to unexpected behavior during reordering or nesting.","severity":"gotcha","affected_versions":">=2.x"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Verify that all objects in your `nestableItems` array (or whatever data source you're using) have a unique `id` property, or configure `keyProp` to match your actual identifier field.","cause":"An item in the `v-model` array is missing the expected unique identifier property (default `id`).","error":"TypeError: Cannot read properties of undefined (reading 'id')"},{"fix":"Ensure your `vue-nestable-handle` uses `slot-scope=\"{ item }\"` (for Vue 2) and `v-bind:item=\"item\"` or shorthand `:item=\"item\"` to pass the item object correctly.","cause":"The `item` prop was not correctly passed to the `vue-nestable-handle` component within the slot, likely due to a `slot-scope` destructuring error or omission.","error":"Vue warn]: Invalid prop: type check failed for prop \"item\". Expected Object, got Undefined."},{"fix":"Sanitize the `id` values of your list items to only include alphanumeric characters, hyphens, and underscores, which are safe for use as CSS class names. Update affected items in your data model.","cause":"An item's `id` property contains characters that are not valid in a CSS class name (e.g., `:`, `,`, `.`, `;`).","error":"Error: The provided id contains invalid characters."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}