{"id":19747031,"url":"https://github.com/phphe/vue-draggable-nested-tree","last_synced_at":"2025-04-12T15:33:10.220Z","repository":{"id":32062566,"uuid":"130532839","full_name":"phphe/vue-draggable-nested-tree","owner":"phphe","description":"Vue2 draggable tree component","archived":false,"fork":false,"pushed_at":"2024-04-15T14:40:03.000Z","size":2586,"stargazers_count":338,"open_issues_count":59,"forks_count":62,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-05-20T15:24:37.150Z","etag":null,"topics":["draggable","draggableview","nested","sorted","tree-structure","treeview","vue-component","vue-tree"],"latest_commit_sha":null,"homepage":"https://hetree.phphe.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phphe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-22T03:44:13.000Z","updated_at":"2024-06-18T14:07:32.497Z","dependencies_parsed_at":"2024-06-18T14:07:17.224Z","dependency_job_id":"5c2f02e3-aeb1-4c78-85bc-e90d5130303c","html_url":"https://github.com/phphe/vue-draggable-nested-tree","commit_stats":{"total_commits":92,"total_committers":4,"mean_commits":23.0,"dds":0.03260869565217395,"last_synced_commit":"11861271062eb517fbb5e207e29a3e0ec6b4e391"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phphe%2Fvue-draggable-nested-tree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phphe%2Fvue-draggable-nested-tree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phphe%2Fvue-draggable-nested-tree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phphe%2Fvue-draggable-nested-tree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phphe","download_url":"https://codeload.github.com/phphe/vue-draggable-nested-tree/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248589875,"owners_count":21129693,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["draggable","draggableview","nested","sorted","tree-structure","treeview","vue-component","vue-tree"],"created_at":"2024-11-12T02:16:41.915Z","updated_at":"2025-04-12T15:33:10.193Z","avatar_url":"https://github.com/phphe.png","language":"JavaScript","funding_links":["https://www.paypal.me/phphe"],"categories":["JavaScript","UI组件","Components \u0026 Libraries","UI Components"],"sub_categories":["树","UI Components","Tree"],"readme":"\u003ca name=\"vue_draggable_nested_tree\"\u003e\u003c/a\u003e\n\n# vue-draggable-nested-tree vue 可拖拽树, 可跨树拖拽\n\n**This project is no longer maintained, please move to the new monorepo [he-tree](https://github.com/phphe/he-tree).**\n\n**本项目不再维护, 请移步到新的 monorepo [he-tree](https://github.com/phphe/he-tree).**\n\n这是可拖拽树组件. 此组件没有 css, 您需要自己添加您喜欢的样式, 参考 demo, 只有几个样式, 不难.\n此组件不负责节点的具体渲染, 暴露了一个节点渲染插槽, 请参考 demo 自行渲染.  \nThis is a draggable tree component. This component does not have css, you need to add your style refer to demo. The demo style is less, not difficult.\nThis component doesn't render node. It exposes a node rendering slot. Please refer to the demo for rendering.\n\n- [demo / 示例/演示](https://codepen.io/phphe/pen/KRapQm)\n- [ie11 example / ie11 示例](https://github.com/phphe/vue-draggable-nested-tree/tree/master/ie11-example)\n- [English Doc](https://github.com/phphe/vue-draggable-nested-tree/blob/master/README.md)\n- [中文文档](https://github.com/phphe/vue-draggable-nested-tree/blob/master/README_CN.md)\n- [한국어 Korean](https://github.com/phphe/vue-draggable-nested-tree/blob/master/README_ko.md) by [cjstk7168](https://github.com/cjstk7168)\n\n# touch\n\n已支持简单触摸(单点).  \nSupport touch(single point).\n\n# Donation / 打赏\n\n[Paypal](https://www.paypal.me/phphe) | [Alipay/支付宝](https://github.com/phphe/my-alipay-wechat-qr-code/blob/master/alipay.jpg) | [Wechat/微信](https://github.com/phphe/my-alipay-wechat-qr-code/blob/master/wechat.png)\n\n# Indexes\n\n- [vue-draggable-nested-tree](#vue_draggable_nested_tree)\n- [install](#install)\n- [usage](#usage)\n  - [import](#import)\n  - [data](#data)\n  - [template](#template)\n  - [template for old browsers(eg: IE)](#template_for_old_browsers)\n- [api](#api)\n  - [Tree props](#tree_props)\n    - [Noraml - Tree props](#noraml_tree_props)\n    - [Hooks - Tree props](#hooks_tree_props)\n    - [draggableHelperInfo: {event, options, store}](#draggable_helper_info)\n  - [Tree properties](#tree_properties)\n  - [Tree events](#tree_events)\n  - [Tree methods](#tree_methods)\n  - [node properties](#node_properties)\n  - [node deep properties example](#node_deep_properties_example)\n- [other](#other)\n  - [demo css](#demo_css)\n  - [examples](#examples)\n  - [draggable \u0026 droppable](#draggable_\u0026_droppable)\n  - [Traverse tree](#traverse_tree)\n  - [draggable library](#draggable_library)\n\n\u003ca name=\"install\"\u003e\u003c/a\u003e\n\n# install\n\n```sh\nnpm i vue-draggable-nested-tree\n```\n\n\u003ca name=\"usage\"\u003e\u003c/a\u003e\n\n# usage\n\n\u003ca name=\"import\"\u003e\u003c/a\u003e\n\n### import\n\n```js\nimport { DraggableTree } from \"vue-draggable-nested-tree\";\n// vue-draggable-nested-tree contains Tree, TreeNode, DraggableTree, DraggableTreeNode\n// import the component and register it as global or local component\n```\n\n\u003ca name=\"data\"\u003e\u003c/a\u003e\n\n### data\n\n```js\ndata: [\n  { text: \"node 1\" },\n  { text: \"node 2\" },\n  { text: \"node 3 undraggable\", draggable: false },\n  { text: \"node 4\" },\n  { text: \"node 4 undroppable\", droppable: false },\n  {\n    text: \"node 5\",\n    children: [\n      { text: \"node 1\" },\n      { text: \"node 2\", children: [{ text: \"node 3\" }, { text: \"node 4\" }] },\n      {\n        text: \"node 2 undroppable\",\n        droppable: false,\n        children: [{ text: \"node 3\" }, { text: \"node 4\" }],\n      },\n      {\n        text: \"node 2\",\n        children: [\n          { text: \"node 3\" },\n          { text: \"node 4 undroppable\", droppable: false },\n        ],\n      },\n      { text: \"node 3\" },\n      { text: \"node 4\" },\n      { text: \"node 3\" },\n      { text: \"node 4\" },\n      { text: \"node 3\" },\n      { text: \"node 4\" },\n      { text: \"node 3\" },\n      { text: \"node 4\" },\n    ],\n  },\n];\n```\n\n\u003ca name=\"template\"\u003e\u003c/a\u003e\n\n### template\n\n```pug\nTree(:data=\"data\" draggable crossTree)\n  div(slot-scope=\"{data, store, vm}\")\n    //- data is node\n    //- store is the tree\n    //- vm is node Vue instance, you can get node level by vm.level\n    template(v-if=\"!data.isDragPlaceHolder\")\n      b(v-if=\"data.children \u0026\u0026 data.children.length\" @click=\"store.toggleOpen(data)\") {{data.open ? '-' : '+'}}\u0026nbsp;\n      span {{data.text}}\n```\n\n\u003ca name=\"template_for_old_browsers\"\u003e\u003c/a\u003e\n\n### template for old browsers(eg: IE)\n\n```pug\n//- slot-scope=\"{data, store, vm}\" may not work in old browsers, replace with slot-scope=\"slot\"\nTree(:data=\"data\" draggable crossTree)\n  div(slot-scope=\"slot\")\n    //- data is node\n    //- store is the tree\n    //- vm is node Vue instance, you can get node level by vm.level\n    template(v-if=\"!slot.data.isDragPlaceHolder\")\n      b(v-if=\"slot.data.children \u0026\u0026 slot.data.children.length\" @click=\"slot.store.toggleOpen(slot.data)\") {{slot.data.open ? '-' : '+'}}\u0026nbsp;\n      span {{slot.data.text}}\n```\n\n\u003ca name=\"api\"\u003e\u003c/a\u003e\n\n# api\n\n**The 'store' is the tree vm**\n\u003ca name=\"tree_props\"\u003e\u003c/a\u003e\n\n### Tree props\n\n\u003ca name=\"noraml_tree_props\"\u003e\u003c/a\u003e\n\n###### Noraml - Tree props\n\n```js\n// base tree\ndata: {}, // type Array\nindent: {default: 16},\nactivatedClass: {default: 'active'},\nopenedClass: {default: 'open'},\nspace: {default: 10}, // space between node, unit px\n// draggable tree\npreventSelect: {default: true}, // if to prevent drag handler text be selected when drag, excluding input and textarea\ngetTriggerEl: {type: Function}, // get the el trigger drag, default is node self. arguments(nodeVm)\ndraggable: {}, // is the tree draggable, default false\ndroppable: {default: true}, // is the tree droppable, default true\ncrossTree: {}, // can a node of the tree be dragged into other tree, or receive other tree node\n```\n\n\u003ca name=\"hooks_tree_props\"\u003e\u003c/a\u003e\n\n###### Hooks - Tree props\n\n```js\nondragstart: {type: Function}, // hook. return false to prevent drag. arguments(node, draggableHelperInfo)\nondragend: {type: Function}, // hook. return false to prevent drop. arguments(node, draggableHelperInfo)\n```\n\n\u003ca name=\"draggable_helper_info\"\u003e\u003c/a\u003e\n\n###### draggableHelperInfo\n\n{event, options, store}\n\u003ca name=\"tree_properties\"\u003e\u003c/a\u003e\n\n### Tree properties\n\n```js\n// base\nrootData, // generated by tree\n// draggable\ndplh, // drag placeholder. globally unique.\ntrees, // array, all trees in the app. globally unique.\n```\n\n\u003ca name=\"tree_events\"\u003e\u003c/a\u003e\n\n### Tree events\n\n```js\n// store is the tree vm\ndrag(node), // on drag start.\n  drop(node, targetTree, oldTree), // after drop.\n  change(node, targetTree, oldTree), // after drop, only when the node position changed\n  nodeOpenChanged(node); // on a node is closed or open\n```\n\n- targetTree and oldTree are tree vm.\n- oldTree is available only when cross tree. Otherwise null.\n- if cross tree, both targetTree and oldTree will emit drop and change.\n\n\u003ca name=\"tree_methods\"\u003e\u003c/a\u003e\n\n### Tree methods\n\n```js\npure(node, withChildren, after)\n/*\npure\nreturn a node data without runtime properties.(!: property which starts with '_' will be removed)\nwithChildren: optional. after: Function, optional\nthe code about after(t is computed node data):\nif (after) {\n  return after(t, node) || t\n}\nreturn t\n*/\ngetNodeById(id)\ngetActivated()\ngetOpened()\nactiveNode(node, inactiveOld)\ntoggleActive(node, inactiveOld)\nopenNode(node, closeOld)\ntoggleOpen(node, closeOld)\n// follow methods are easy, so I paste their soure code\ngetPureData(after) { return this.pure(this.rootData, true, after).children } // after: Function, optional\ndeleteNode(node) { return hp.arrayRemove(node.parent.children, node) }\n// add node: like array. eg: node.children.push(newNodeData)\n// update node: just assign to the node properties directly\nisNodeDraggable(node)\nisNodeDroppable(node)\n```\n\n\u003ca name=\"node_properties\"\u003e\u003c/a\u003e\n\n### node properties\n\n```js\n// base\n_id\n_vm\nparent\nchildren: [],\nopen,\nactive: false,\nstyle: {},\nclass: '',\ninnerStyle: {},\ninnerClass: '',\ninnerBackStyle: {},\ninnerBackClass: {},\n// draggable\ndraggable // default true. Please check 'draggable \u0026 droppable' below\ndroppable // default true. Please check 'draggable \u0026 droppable' below\nisDragPlaceHolder\n```\n\n\u003ca name=\"node_deep_properties_example\"\u003e\u003c/a\u003e\n\n#### node deep properties example\n\n```js\nnode._vm; // vm\nnode._vm.level; // 节点层级, 只读\nnode._vm.store; // tree\nnode.parent._vm; // parent node vm\nnode._vm.store;\n```\n\n\u003ca name=\"other\"\u003e\u003c/a\u003e\n\n# other\n\n\u003ca name=\"demo_css\"\u003e\u003c/a\u003e\n\n### demo css\n\n```css\n.he-tree {\n  border: 1px solid #ccc;\n  padding: 20px;\n  width: 300px;\n}\n.tree-node {\n}\n.tree-node-inner {\n  padding: 5px;\n  border: 1px solid #ccc;\n  cursor: pointer;\n}\n.draggable-placeholder {\n}\n.draggable-placeholder-inner {\n  border: 1px dashed #0088f8;\n  box-sizing: border-box;\n  background: rgba(0, 136, 249, 0.09);\n  color: #0088f9;\n  text-align: center;\n  padding: 0;\n  display: flex;\n  align-items: center;\n}\n```\n\n\u003ca name=\"examples\"\u003e\u003c/a\u003e\n\n### examples\n\nclone the package, and\n\n```sh\nnpm install\nnpm run dev\n```\n\n- [Base](https://github.com/phphe/vue-draggable-nested-tree/blob/master/src/examples/Base.vue)\n- [MaxLevel](https://github.com/phphe/vue-draggable-nested-tree/blob/master/src/examples/MaxLevel.vue)\n\n\u003ca name=\"draggable_\u0026_droppable\"\u003e\u003c/a\u003e\n\n### draggable \u0026 droppable\n\nA node is default draggable and droppable. You can set draggable and droppable property of a node. The another way is listen event 'drag', traverse all data to set draggable or droppable property.\n\u003ca name=\"traverse_tree\"\u003e\u003c/a\u003e\n\n### Traverse tree\n\nRecommend to use my other library [tree-helper](https://github.com/phphe/tree-helper). It has 2 traverse methods: depthFirstSearch, breadthFirstSearch.\n\u003ca name=\"draggable_library\"\u003e\u003c/a\u003e\n\n### draggable library\n\n[draggable-helper](https://github.com/phphe/draggable-helper) is my another library for drag. And it also is using by this component. You can use it to help you drag functions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphphe%2Fvue-draggable-nested-tree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphphe%2Fvue-draggable-nested-tree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphphe%2Fvue-draggable-nested-tree/lists"}