Vue Nestable

raw JSON →
2.6.0 verified Sat Apr 25 auth: no javascript

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.

error TypeError: Cannot read properties of undefined (reading 'id')
cause An item in the `v-model` array is missing the expected unique identifier property (default `id`).
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.
error Vue warn]: Invalid prop: type check failed for prop "item". Expected Object, got Undefined.
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.
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.
error Error: The provided id contains invalid characters.
cause An item's `id` property contains characters that are not valid in a CSS class name (e.g., `:`, `,`, `.`, `;`).
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.
breaking 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.
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.
gotcha 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 `;`.
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.
gotcha 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.
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.
gotcha 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.
fix Always bind `:item="item"` and provide a unique `:key="item.id"` (or corresponding `keyProp`) to `vue-nestable-handle` within your `slot-scope` template.
npm install vue-nestable
yarn add vue-nestable
pnpm add vue-nestable

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.

<template>
  <div id="app">
    <h1>My Nestable List</h1>
    <vue-nestable v-model="nestableItems" :maxDepth="3">
      <vue-nestable-handle
        slot-scope="{ item }"
        :item="item"
        :key="item.id"
        class="nestable-item"
      >
        {{ item.text }} (ID: {{ item.id }})
      </vue-nestable-handle>
    </vue-nestable>
    <pre>{{ JSON.stringify(nestableItems, null, 2) }}</pre>
  </div>
</template>

<script>
import Vue from 'vue';
import { VueNestable, VueNestableHandle } from 'vue-nestable';

Vue.component('VueNestable', VueNestable);
Vue.component('VueNestableHandle', VueNestableHandle);

export default {
  name: 'App',
  data() {
    return {
      nestableItems: [
        { id: 0, text: 'Task Alpha' },
        { id: 1, text: 'Task Beta', children: [{ id: 2, text: 'Subtask Gamma' }] },
        { id: 3, text: 'Task Delta' },
        { id: 4, text: 'Task Epsilon', children: [{ id: 5, text: 'Subtask Zeta' }] }
      ]
    };
  }
};
</script>

<style>
/* Basic styling for demo purposes */
.nestable-item {
  padding: 10px;
  margin: 5px 0;
  border: 1px solid #ddd;
  background: #f9f9f9;
  cursor: grab;
}
.nestable-item:active {
  cursor: grabbing;
}
</style>