Guide
Replace 3 to 2 for Vue2 in follow doc.
Installation#
# Vue3
npm i -P @he-tree/vue3
# Vue2
npm i -P @he-tree/vue2
Import#
import { BaseTree, Draggable, obj, BaseNode, Node } from '@he-tree/vue3'
import '@he-tree/vue3/dist/he-tree-vue3.css'
Don't use margin out of node#
You may want to use margin-bottom
to set the space between two nodes, that is not allowed. If so, it can't get the correct height of node. Use prop gap
to do that.
treeData or flatData#
The tree is able to receive both tree data and flat data as initial data. When use treeData
, tree need childrenKey
. When use flatData
, it need idKey
, parentIdKey
.
treeData
example:
treeData = [
{
text: 'node1',
children: [{ text: 'node1-1' }, { text: 'node1-2' }, { text: 'node1-3' }],
},
{ text: 'node2' },
]
flatData
example:
flatData = [
{ text: 'node1', id: 1 },
{ text: 'node2', id: 2 },
{ text: 'node1-1', id: 3, pid: 1 },
{ text: 'node1-2', id: 3, pid: 1 },
{ text: 'node1-3', id: 3, pid: 1 },
]
Structure#
.he-tree(:id="treeID" :class="{'he-tree-dragging':dragging, 'he-tree-rtl': rtl}")
.vl-items
.tree-node-outer(:data-id="node.$id" :class="node.$outerClass" :style="node.$outerClass")
.tree-node(:class="node.$nodeClass" :style="node.$nodeStyle")
slot(:node="node" :tree="tree") {{node[textKey]}}
.tree-node-outer(:data-id="node.$id" :class="node.$outerClass" :style="node.$outerClass")
.tree-node(:class="node.$nodeClass" :style="node.$nodeStyle")
slot(:node="node" :tree="tree") {{node[textKey]}}
...
It is rendered as a flat list, not nested tree. Different level node has different padding-left
. Refer to the structure above, you can do:
- Set outer element class and style by set
node.$outerClass
andnode.$outerStyle
- Set node element class and style by set
node.$nodeClass
andnode.$nodeStyle
- Use default slot to customize node render. The slot has props: node, tree.
Usage#
<template>
<BaseTree :flatData="flatData" idKey="id" parentIdKey="pid" />
</template>
<script>
import '@he-tree/vue3/dist/he-tree-vue3.css'
import { BaseTree } from '@he-tree/vue3'
export default {
components: { BaseTree },
data() {
return {
flatData: [
{ text: 'node1', id: 1 },
{ text: 'node2', id: 2 },
{ text: 'node1-1', id: 3, pid: 1 },
{ text: 'node1-2', id: 3, pid: 1 },
{ text: 'node1-3', id: 3, pid: 1 },
],
}
},
}
</script>
Ouput#
Use methods outputNestedData
or outputFlatData
to get converted data without runtime properties. In order to get the changed data when drag, they should be executed in the drop
or drop-change
event.
Fold & Expand#
<template>
<BaseTree :flatData="flatData" idKey="id" parentIdKey="pid">
<template v-slot="{ node, tree }">
<b @click="tree.toggleFold(node)">{{ node.$folded ? '+' : '-' }}</b>
<span>{{ node.text }}</span>
</template>
</BaseTree>
</template>
<script>
import '@he-tree/vue3/dist/he-tree-vue3.css'
import { BaseTree } from '@he-tree/vue3'
export default {
components: { BaseTree },
data() {
return {
flatData: [
{ text: 'node1', id: 1 },
{ text: 'node2', id: 2 },
{ text: 'node1-1', id: 3, pid: 1 },
{ text: 'node1-2', id: 3, pid: 1 },
{ text: 'node1-3', id: 3, pid: 1 },
],
}
},
}
</script>
Lazy Load#
Load children data when unfold a node. Such as by Ajax. Use prop childrenLazyLoading
to enable. Use function prop childrenLoader
to load data, it can return Promise
and must return tree data, nested data.
Folde all nodes by default#
Use prop defaultFolded
.
Checkbox#
Use method getAllCheckedNodes
to get all checked nodes.
<template>
<BaseTree :flatData="flatData" idKey="id" parentIdKey="pid">
<template v-slot="{ node, tree }">
<input
type="checkbox"
v-model="node.$checked"
@change="tree.updateChecked(node)"
/>
<span>{{ node.text }}</span>
</template>
</BaseTree>
</template>
<script>
import '@he-tree/vue3/dist/he-tree-vue3.css'
import { BaseTree } from '@he-tree/vue3'
export default {
components: { BaseTree },
data() {
return {
flatData: [
{ text: 'node1', id: 1 },
{ text: 'node2', id: 2 },
{ text: 'node1-1', id: 3, pid: 1 },
{ text: 'node1-2', id: 3, pid: 1 },
{ text: 'node1-3', id: 3, pid: 1 },
],
}
},
}
</script>
RTL#
Use prop rtl
to enable.
Virtualization#
Improve performance when there are a lot of nodes. Use prop virtualization
to enable. Use prop virtualizationPrerender
to define render length at start.
Must add style overflow:auto
for tree. And set height. The height can be fixed value. Use max-height
or display:flex
to set dynamic height also works.
<Draggable virtualization style="height:300px;overflow:auto" />
You can use follow code update virtualization list manually:
tree.$refs.virtualizationList.update()
Draggable#
<template>
<Draggable :flatData="flatData" idKey="id" parentIdKey="pid" />
</template>
<script>
import '@he-tree/vue3/dist/he-tree-vue3.css'
import { Draggable } from '@he-tree/vue3'
export default {
components: { Draggable },
data() {
return {
flatData: [
{ text: 'node1', id: 1 },
{ text: 'node2', id: 2 },
{ text: 'node1-1', id: 3, pid: 1 },
{ text: 'node1-2', id: 3, pid: 1 },
{ text: 'node1-3', id: 3, pid: 1 },
],
}
},
}
</script>
Drag Trigger#
Use prop triggerClass
to specify the css name of the element that triggers the drag. When prop triggerBySelf
true, the child element can't trigger drag.
Prevent Drag#
- When prop
draggable
false, the tree's any nodes can't be drag. - Use prop
eachDraggable
before drag start. - When prop
rootDraggable
false, the root nodes(level 1) can't be dragged. - Use hook prop
ondragstart
before drag start. - Set
node.$draggable
false to handle single node. - When parent node is not draggable, child node is draggable, such as set
$draggable
as true of child node, then this child node is draggable.
Prevent Drop#
- When prop
droppable
false, any nodes can't be dropped in to the tree. - Use prop
eachDroppable
when drag over a node. - When prop
rootDroppable
false, the root (level 1) can't be dropped. - Use hook prop
ondragend
before drop end.ondragend
supports promise. - Set
node.$droppable
false to handle single node. - When parent node is not droppable, child node is droppable, such as set
$droppable
as true of child node, then this child node is droppable.
Runtime data in drag and drop process#
Check tree.store
Placeholder#
When dragging, an element will be generated with a default light cyan background to identify the place where can be dropped. Use hook prop afterPlaceholderCreated
to handle it. If you want to manipulate this element such as adding text, you can only use native JS operations.
Open folded node when dragging#
When dragging a node over a collapsed node, this node is opened by default for dragging into it. It can be controlled by prop unfoldWhenDragover
. Related prop: unfoldWhenDragoverDelay
, isNodeUnfoldable
How to locate the dragging node#
The top left corner of dragging node is used by default. Mouse position is also supported. draggingNodePositionMode
Edge Scroll#
This function belongs to Draggable plugin. If the tree is in a scroll box, it needs to be automatically scrolled when dragged to its edge. This prop is diabled by default. Use prop edgeScroll
control that. Related prop: edgeScrollTriggerMargin, edgeScrollSpeed, edgeScrollTriggerMode.
Touch#
It works in touch devices. It will prevent default action when touch by drag, but sometimes that does not work. Use follow css to prevent default touch action such as scroll. The css target is the drag trigger element. If no drag trigger, it is .tree-node
.
touch-action: none;
Max Level#
To limit the max level of the tree when drag. Use prop eachDroppable
. Follow example code works in Vue2 and Vue3.
<Draggable :eachDroppable="eachDroppable" />
data() {
return {
eachDroppable: (node, store, options, startTree) => {
const maxLevel = 3; // change it by your requirement
let draggingNodeMaxLevel = 0;
hp.walkTreeData(
store.draggingNode,
(childNode) => {
if (childNode.$level > draggingNodeMaxLevel) {
draggingNodeMaxLevel = childNode.$level;
}
},
"$children"
);
draggingNodeMaxLevel = draggingNodeMaxLevel - store.draggingNode.$level;
if (node.$level + draggingNodeMaxLevel >= maxLevel) {
return false;
}
},
}
}
Pro Plugin#
The pro plugin has advanced features.
- Cross tree. Drag from a tree to another tree.
- Clone. Clone node when drag start.
Import by script tag#
Download the latest version from npm, upload dist
folder to your server. You can access the library through gloabl variable heTreeVue3
or heTreeVue2
.
<!-- replace vue3 to vue2 if use Vue2 -->
<script src="yourpath/dist/he-tree-vue3.min.js" charset="utf-8"></script>
<link rel="stylesheet" href="yourpath/dist/he-tree-vue3.css" />
<!-- usage -->
<script type="text/javascript">
var Tree = heTreeVue3.BaseTree;
var Fold = heTreeVue3.Draggable;
...
</script>