这是可拖拽树组件. 此组件没有css, 您需要自己添加您喜欢的样式, 参考demo, 只有几个样式, 不难.
此组件不负责节点的具体渲染, 暴露了一个节点渲染插槽, 请参考demo自行渲染.
This 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.
This component doesn't render node. It exposes a node rendering slot. Please refer to the demo for rendering.
demo
npm i vue-draggable-nested-tree
import {DraggableTree} from 'vue-draggable-nested-tree'
// vue-draggable-nested-tree contains Tree, TreeNode, DraggableTree, DraggableTreeNode
// import the component and register it as global or local component
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'},
]},
]
Tree(:data="data" draggable crossTree)
div(slot-scope="{data, store}")
template(v-if="!data.isDragPlaceHolder")
b(v-if="data.children && data.children.length" @click="store.toggleOpen(data)") {{data.open ? '-' : '+'}}
span {{data.text}}
// base tree
data: {},
indent: {default: 16},
activatedClass: {default: 'active'},
openedClass: {default: 'open'},
space: {default: 10}, // space between node, unit px
// draggable tree
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
ondragstart: {type: Function}, // hook. return false to prevent drag. arguments(node, draggableHelperInfo)
ondragend: {type: Function}, // hook. return false to prevent drop. arguments(node, draggableHelperInfo)
// base
rootData, // generated by tree
// draggable
dplh, // drag placeholder. globally unique.
trees, // array, all trees in the app. globally unique.
// 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
- targetTree and oldTree are tree vm.
- oldTree is available only when cross tree. Otherwise null.
- if cross tree, both targetTree and oldTree will emit drop and change targetTree and oldTree.
pure(node, withChildren) // return a node data without runtime properties.(!: property which starts with '_' will be removed)
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() { return this.pure(this.rootData, true).children }
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
// base
_id
_vm
parent
children: [],
open,
level,
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._vm // vm
node._vm.store // tree
node.parent._vm // parent node vm
node._vm.store.
.he-tree{
border: 1px solid #ccc;
padding: 20px;
width: 300px;
}
.tree-node{
}
.tree-node-inner{
padding: 5px;
border: 1px solid #ccc;
cursor: pointer;
}
.draggable-placeholder{
}
.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;
}
clone the package, and
npm install
npm run dev
A 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.
Recommend to use my other library tree-helper. It has 2 traverse methods: depthFirstSearch, breadthFirstSearch.
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.