{"id":11027,"library":"he-tree-vue","title":"Vue Draggable Sortable Tree Component","description":"he-tree-vue is a robust Vue 3 component library designed for rendering draggable, sortable, and nested tree structures. Currently at stable version 3.1.2, it is actively maintained with a development-driven release cadence, focusing on bug fixes, performance improvements, and alignment with modern Vue ecosystem features. Key differentiators include comprehensive TypeScript definitions for enhanced developer experience, a built-in dragging placeholder for intuitive user interaction, and full compatibility with Vue 3's Composition API. It provides a powerful solution for managing hierarchical data with advanced interaction capabilities, distinguishing itself from simpler tree components by its focus on comprehensive drag-and-drop functionality.","status":"active","version":"3.1.2","language":"javascript","source_language":"en","source_url":"https://github.com/phphe/he-tree-vue","tags":["javascript","typescript"],"install":[{"cmd":"npm install he-tree-vue","lang":"bash","label":"npm"},{"cmd":"yarn add he-tree-vue","lang":"bash","label":"yarn"},{"cmd":"pnpm add he-tree-vue","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required as a peer dependency for rendering the tree component within a Vue 3 application.","package":"vue","optional":false}],"imports":[{"note":"Draggable is the main component for a draggable and sortable tree. CommonJS `require` is not supported in modern Vue 3/Vite projects; use ES Module `import`.","wrong":"const Draggable = require('he-tree-vue').Draggable","symbol":"Draggable","correct":"import { Draggable } from 'he-tree-vue'"},{"note":"BaseTree is the foundational tree component that Draggable extends. Useful for basic, non-draggable trees.","symbol":"BaseTree","correct":"import { BaseTree } from 'he-tree-vue'"},{"note":"Import types for enhanced type safety when defining your tree data structure. The library provides comprehensive TypeScript definitions.","symbol":"TreeDataItem","correct":"import type { TreeDataItem } from 'he-tree-vue'"},{"note":"Essential default styles for the tree component, including placeholders and basic layout. Omission will result in an unstyled component.","symbol":"CSS Styles","correct":"import 'he-tree-vue/style/default.css'"}],"quickstart":{"code":"<template>\n  <div id=\"app\">\n    <h1>My Draggable Tree</h1>\n    <Draggable\n      v-model=\"treeData\"\n      :indent=\"20\"\n      :eachNodeAttributes=\"(node) => ({ 'data-id': node.id })\"\n      @change=\"onTreeChange\"\n      @node-drop=\"onNodeDrop\"\n      class=\"my-custom-tree\"\n    >\n      <template #default=\"{ node, index, path, tree }\">\n        <div class=\"tree-node-back\">\n          {{ node.text }}\n          <button @click=\"addNode(node)\">Add Child</button>\n        </div>\n      </template>\n    </Draggable>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { Draggable, type TreeDataItem } from 'he-tree-vue';\nimport 'he-tree-vue/style/default.css';\n\ninterface MyTreeDataItem extends TreeDataItem {\n  id: number;\n  text: string;\n  children?: MyTreeDataItem[];\n}\n\nlet nextId = 4;\n\nconst treeData = ref<MyTreeDataItem[]>([\n  { id: 1, text: 'Node 1', children: [\n    { id: 2, text: 'Node 1.1' },\n    { id: 3, text: 'Node 1.2' }\n  ]}\n]);\n\nconst onTreeChange = (data: MyTreeDataItem[]) => {\n  console.log('Tree data changed:', data);\n};\n\nconst onNodeDrop = (dragInfo: any) => {\n  console.log('Node dropped:', dragInfo);\n  // You might want to persist the updated treeData to a backend here\n};\n\nconst addNode = (parentNode: MyTreeDataItem) => {\n  if (!parentNode.children) {\n    parentNode.children = [];\n  }\n  const newNode: MyTreeDataItem = { id: nextId++, text: `New Child of ${parentNode.text}` };\n  parentNode.children.push(newNode);\n  console.log('Added new node:', newNode);\n};\n</script>\n\n<style>\n.my-custom-tree {\n  border: 1px solid #eee;\n  padding: 10px;\n  min-height: 100px;\n}\n.tree-node-back {\n  padding: 5px;\n  border: 1px solid #ccc;\n  margin: 2px 0;\n  background-color: #f9f9f9;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n}\n.he-tree-drag-placeholder {\n  background-color: #e0f2f7 !important; /* Light blue placeholder */\n  border: 1px dashed #90caf9 !important;\n}\n</style>\n","lang":"typescript","description":"Demonstrates a basic draggable and sortable tree component using `he-tree-vue` with Vue 3's `<script setup>`, TypeScript, and custom styling. It shows data binding, event handling for drag-and-drop, and dynamic node addition."},"warnings":[{"fix":"Consult the official Vue 3 Migration Guide (v3.vuejs.org/guide/migration/introduction.html) and update your entire Vue application and its dependencies to Vue 3 before integrating `he-tree-vue`.","message":"This library is designed for Vue 3. Migrating an existing Vue 2 application or components to use `he-tree-vue` will require a full Vue 3 migration, which involves significant breaking changes to global APIs, template directives, component options, and reactivity system. It is not a drop-in replacement for Vue 2 tree components.","severity":"breaking","affected_versions":"<3.0.0 (when migrating from Vue 2)"},{"fix":"Always check the `updateBehavior` prop and set it to `'new'` if your state management system (e.g., Pinia, Vuex) requires immutable data updates or if you prefer a new data object on changes to simplify change detection. Otherwise, be aware that the original `v-model` array/object will be mutated directly.","message":"The `updateBehavior` prop controls how `v-model` data changes are emitted. By default ('modify'), it directly modifies the bound data. If set to 'new', it emits a completely new data object. This is crucial for state management patterns (e.g., Vuex/Pinia) where immutability might be preferred or required.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Avoid applying custom `padding-left` directly to `.tree-node-back` or similar internal elements. Adjust indentation using the `indent` prop provided by the component or other CSS properties like `margin-left` on parent elements if necessary, ensuring not to interfere with the component's internal indentation styling.","message":"The component relies on JavaScript to set the `padding-left` for indentation of `tree-node-back` elements. Overriding this with custom CSS `padding-left` will break the tree's visual structure and indentation logic.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change `const { Draggable } = require('he-tree-vue')` to `import { Draggable } from 'he-tree-vue'` and ensure your project's build configuration (e.g., `vite.config.ts`) is set up for ES Modules.","cause":"Attempting to use CommonJS `require()` syntax in a modern Vue 3 project (e.g., with Vite or a browser-based bundler that expects ES Modules).","error":"Uncaught ReferenceError: require is not defined"},{"fix":"Ensure your project explicitly installs Vue 3 (`npm install vue@^3.0.0`) and that no other dependencies are forcing Vue 2. If migrating, fully upgrade your project to Vue 3. Use `npm install --legacy-peer-deps` as a temporary workaround if direct resolution is difficult, but prioritize fixing the dependency tree.","cause":"`he-tree-vue` is a Vue 3 component, but your project is either using Vue 2 or has a conflicting Vue 2 dependency in its tree.","error":"npm ERR! ERESOLVE unable to resolve dependency tree \\n npm ERR! Found: vue@^2.x.x \\n npm ERR! Could not resolve dependency: \\n npm ERR! peer vue@\"^3.0.0\" from he-tree-vue@3.x.x"},{"fix":"Define a TypeScript interface for your tree nodes that extends `TreeDataItem` and explicitly includes properties like `text` and `children`, as shown in the quickstart. Ensure all your data objects adhere to this interface.","cause":"Your tree data items do not conform to the expected type `TreeDataItem` or your custom interface for `he-tree-vue`.","error":"Property 'text' does not exist on type 'TreeDataItem' or 'Property 'children' does not exist on type 'TreeDataItem'"}],"ecosystem":"npm"}