Vue draggable tree view component
npm install @jambonn/vue-nested-draggable`` bash`
npm install @jambonn/vue-nested-draggable
or if you prefer yarn
` bash`
yarn add @jambonn/vue-nested-draggable
You may install Vue Nested Draggable globally:
` js
import Vue from 'vue';
import VueNestedDraggable from '@jambonn/vue-nested-draggable';
Vue.component('draggable-tree', VueNestedDraggable.DraggableTree);
`
This will make <draggable-tree> available to all components within your Vue app.
Include the carousel directly into your component using import:
` js
import { DraggableTree } from '@jambonn/vue-nested-draggable';
export default {
...
components: {
DraggableTree
}
...
};
`
js
data: [
{text: 'node 1'},
{text: 'node 2'},
{text: 'node 3 undraggable', draggable: false},
{text: 'node 4'},
{text: 'node 4 undroppable', droppable: false},
{text: 'node 5', children: [
{text: 'node 1'},
{text: 'node 2', children: [
{text: 'node 3'},
{text: 'node 4'},
]},
{text: 'node 2 undroppable', droppable: false, children: [
{text: 'node 3'},
{text: 'node 4'},
]},
{text: 'node 2', children: [
{text: 'node 3'},
{text: 'node 4 undroppable', droppable: false},
]},
{text: 'node 3'},
{text: 'node 4'},
{text: 'node 3'},
{text: 'node 4'},
{text: 'node 3'},
{text: 'node 4'},
{text: 'node 3'},
{text: 'node 4'},
]},
]
`$3
`template
{{data.open ? '-' : '+'}}
{{data.text}}
`Configuration
$3
`js
// base tree
data: {}, // type Array
indent: {default: 16},
activatedClass: {default: 'active'},
openedClass: {default: 'open'}
space: {default: 10}, // space between node, unit px
// draggable tree
preventSelect: {default: true}, // if to prevent drag handler text be selected when drag, excluding input and textarea
getTriggerEl: {type: Function}, // get the el trigger drag, default is node self. arguments(nodeVm)
draggable: {}, // is the tree draggable, default false
droppable: {default: true}, // is the tree droppable, default true
crossTree: {}, // can a node of the tree be dragged into other tree, or receive other tree node
`
$3
`js
ondragstart: {type: Function}, // hook. return false to prevent drag. arguments(node, draggableHelperInfo)
ondragend: {type: Function}, // hook. return false to prevent drop. arguments(node, draggableHelperInfo)
`
$3
{event, options, store}$3
`js
// base
rootData, // generated by tree
// draggable
dplh, // drag placeholder. globally unique.
trees, // array, all trees in the app. globally unique.
`$3
`js
// store is the tree vm
drag(node), // on drag start.
drop(node, targetTree, oldTree), // after drop.
change(node, targetTree, oldTree), // after drop, only when the node position changed
nodeOpenChanged(node) // on a node is closed or open
`$3
`js
pure(node, withChildren, after)
/*
pure
return a node data without runtime properties.(!: property which starts with '_' will be removed)
withChildren: optional. after: Function, optional
the code about after(t is computed node data):
if (after) {
return after(t, node) || t
}
return t
*/
getNodeById(id)
getActivated()
getOpened()
activeNode(node, inactiveOld)
toggleActive(node, inactiveOld)
openNode(node, closeOld)
toggleOpen(node, closeOld)
// follow methods are easy, so I paste their soure code
getPureData(after) { return this.pure(this.rootData, true, after).children } // after: Function, optional
deleteNode(node) { return hp.arrayRemove(node.parent.children, node) }
// add node: like array. eg: node.children.push(newNodeData)
// update node: just assign to the node properties directly
isNodeDraggable(node)
isNodeDroppable(node)
`$3
`js
// base
_id
_vm
parent
children: [],
open,
active: false,
style: {},
class: '',
innerStyle: {},
innerClass: '',
innerBackStyle: {},
innerBackClass: {},
// draggable
draggable // default true. Please check 'draggable & droppable' below
droppable // default true. Please check 'draggable & droppable' below
isDragPlaceHolder
`#### Node deep properties example
`js
node._vm // vm
node._vm.level // 节点层级, 只读
node._vm.store // tree
node.parent._vm // parent node vm
node._vm.store
`#### Node max level
`template
{{data.open ? '-' : '+'}}
{{data.text}}
`
` js
import { DraggableTree, depthFirstSearch } from '@jambonn/vue-nested-draggable';export default {
...
components: {
DraggableTree
},
methods: {
ondrag(node) {
const maxLevel = 2
let nodeLevels = 1
depthFirstSearch(node, childNode => {
if (childNode._vm.level > nodeLevels) {
nodeLevels = childNode._vm.level
}
})
nodeLevels = nodeLevels - node._vm.level + 1
const childNodeMaxLevel = maxLevel - nodeLevels
depthFirstSearch(this.originalData, childNode => {
if (childNode === node) {
return 'skip children'
}
if (!childNode._vm) {
console.log(childNode)
}
this.$set(
childNode,
'droppable',
childNode._vm.level <= childNodeMaxLevel,
)
})
},
},
...
};
`
Other
$3
`css
.he-tree{
border: 1px solid #ccc;
padding: 20px;
width: 300px;
}
.tree-node-inner{
padding: 5px;
border: 1px solid #ccc;
cursor: pointer;
}
.draggable-placeholder-inner{
border: 1px dashed #0088F8;
box-sizing: border-box;
background: rgba(0, 136, 249, 0.09);
color: #0088f9;
text-align: center;
padding: 0;
display: flex;
align-items: center;
}
`Project setup
`
yarn install
`$3
`
yarn serve
`$3
`
yarn build
`$3
`
yarn lint
``