Skip to content

Commit 43fda05

Browse files
committed
2.2.0 move property 'level' from node to node vm. fix issue: #37 (comment)
1 parent 45d9383 commit 43fda05

12 files changed

+141
-88
lines changed

README.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ data: [
8989
### template
9090
```pug
9191
Tree(:data="data" draggable crossTree)
92-
div(slot-scope="{data, store}")
92+
div(slot-scope="{data, store, vm}")
93+
//- data is node
94+
//- store is the tree
95+
//- vm is node Vue instance, you can get node level by vm.level
9396
template(v-if="!data.isDragPlaceHolder")
9497
b(v-if="data.children && data.children.length" @click="store.toggleOpen(data)") {{data.open ? '-' : '+'}} 
9598
span {{data.text}}
@@ -148,7 +151,17 @@ change(node, targetTree, oldTree), // after drop, only when the node position ch
148151
<a name="tree_methods"></a>
149152
### Tree methods
150153
```js
151-
pure(node, withChildren) // return a node data without runtime properties.(!: property which starts with '_' will be removed)
154+
pure(node, withChildren, after)
155+
/*
156+
pure
157+
return a node data without runtime properties.(!: property which starts with '_' will be removed)
158+
withChildren: optional. after: Function, optional
159+
the code about after(t is computed node data):
160+
if (after) {
161+
return after(t, node) || t
162+
}
163+
return t
164+
*/
152165
getNodeById(id)
153166
getActivated()
154167
getOpened()
@@ -157,10 +170,12 @@ toggleActive(node, inactiveOld)
157170
openNode(node, closeOld)
158171
toggleOpen(node, closeOld)
159172
// follow methods are easy, so I paste their soure code
160-
getPureData() { return this.pure(this.rootData, true).children }
173+
getPureData(after) { return this.pure(this.rootData, true, after).children } // after: Function, optional
161174
deleteNode(node) { return hp.arrayRemove(node.parent.children, node) }
162175
// add node: like array. eg: node.children.push(newNodeData)
163176
// update node: just assign to the node properties directly
177+
isNodeDraggable(node)
178+
isNodeDroppable(node)
164179
```
165180
<a name="node_properties"></a>
166181
### node properties
@@ -171,7 +186,6 @@ _vm
171186
parent
172187
children: [],
173188
open,
174-
level,
175189
active: false,
176190
style: {},
177191
class: '',
@@ -188,6 +202,7 @@ isDragPlaceHolder
188202
#### node deep properties example
189203
```js
190204
node._vm // vm
205+
node._vm.level // 节点层级, 只读
191206
node._vm.store // tree
192207
node.parent._vm // parent node vm
193208
node._vm.store

README_CN.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ data: [
8989
### template / 模板
9090
```pug
9191
Tree(:data="data" draggable crossTree)
92-
div(slot-scope="{data, store}")
92+
div(slot-scope="{data, store, vm}")
93+
//- data是节点数据
94+
//- store是树的实例
95+
//- vm是节点实例, vm.level是节点的层级
9396
template(v-if="!data.isDragPlaceHolder")
9497
b(v-if="data.children && data.children.length" @click="store.toggleOpen(data)") {{data.open ? '-' : '+'}}&nbsp;
9598
span {{data.text}}
@@ -149,7 +152,18 @@ change(node, targetTree, oldTree), // 拖动结束后并且有节点位置发生
149152
<a name="tree_methods"></a>
150153
### Tree methods / 树的方法
151154
```js
152-
pure(node, withChildren) // 获得干净数据(不含运行时的属性例如_id之类的), 下划线开头的属性会被删掉. withChildren为true的话则会把节点的子节点的数据也获取到.
155+
156+
pure(node, withChildren, after)
157+
/*
158+
pure
159+
获得干净数据(不含运行时的属性例如_id之类的), 下划线开头的属性会被删掉. withChildren为true的话则会把节点的子节点的数据也获取到.
160+
withChildren: 可选. after: Function, 可选, after可以自定义返回数据
161+
关于after的源码(t是干净的节点数据):
162+
if (after) {
163+
return after(t, node) || t
164+
}
165+
return t
166+
*/
153167
getNodeById(id)
154168
getActivated()
155169
getOpened()
@@ -158,10 +172,12 @@ toggleActive(node, inactiveOld)
158172
openNode(node, closeOld)
159173
toggleOpen(node, closeOld)
160174
// 下面的方法很简单, 所以附上源码.
161-
getPureData() { return this.pure(this.rootData, true).children } // 获取树的干净数据
175+
getPureData(after) { return this.pure(this.rootData, true, after).children } // 获取树的干净数据 after: Function, 可选
162176
deleteNode(node) { return hp.arrayRemove(node.parent.children, node) } // 删除节点
163177
// 增加节点, 像操作数组一样就可以了. 例子: node.children.push(newNodeData)
164178
// 更新节点, 直接修改节点属性就可以了
179+
isNodeDraggable(node) // 判断节点是否draggable
180+
isNodeDroppable(node) // 判断节点是否droppable
165181
```
166182
<a name="node_properties"></a>
167183
### node properties / 节点属性
@@ -172,7 +188,6 @@ _vm // 节点的实例
172188
parent // 父节点
173189
children: [], // 子节点
174190
open, // 是否打开
175-
level, // 节点层级, 根节点为0, 传入的data数组从1开始
176191
active: false,
177192
style: {}, // 可以控制节点的style
178193
class: '', // 可以控制节点的class
@@ -191,6 +206,7 @@ isDragPlaceHolder // 该节点是不是拖动占位节点
191206
在一些回调函数和事件里的参数可能只有node, 而想访问更多(例如节点实例, 节点的爸爸, 节点所在树)怎么办? 其实可以直接通过node访问, 因为他们都嵌套在里面了
192207
```js
193208
node._vm // vm
209+
node._vm.level // node level, readonly
194210
node._vm.store // tree
195211
node.parent._vm // parent node vm
196212
node._vm.store

UPGRADE_GUIDE.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,17 @@ Change to:
1515
Tree
1616
div(slot-scope="{data, store}") {{data.level}}
1717
```
18+
### 2.1.8 -> 2.2.0
19+
20+
#### `level` moved into node vm from node. `vm` add to slot props
21+
22+
```pug
23+
Tree
24+
div(slot-scope="{data, store}") {{data.level}}
25+
```
26+
Change to:
27+
28+
```pug
29+
Tree
30+
div(slot-scope="{data, store, vm}") {{vm.level}}
31+
```

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-draggable-nested-tree",
3-
"version": "2.1.8",
3+
"version": "2.2.0",
44
"description": "A draggable tree view component for vue2",
55
"main": "dist/vue-draggable-nested-tree.cjs.js",
66
"module": "dist/vue-draggable-nested-tree.es.js",
@@ -87,4 +87,4 @@
8787
"last 2 versions",
8888
"not ie <= 8"
8989
]
90-
}
90+
}

src/components/DraggableTreeNode.vue

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import * as hp from 'helper-js'
33
import * as th from 'tree-helper'
44
import draggableHelper from 'draggable-helper'
55
import TreeNode from './TreeNode.vue'
6-
import autoMoveDragPlaceHolder from './autoMoveDragPlaceHolder'
6+
import autoMoveDragPlaceHolder, {isNodeDraggable, isNodeDroppable} from './autoMoveDragPlaceHolder'
77
import * as ut from '../plugins/utils'
88
99
export default {
1010
extends: TreeNode,
1111
name: 'TreeNode',
1212
mounted() {
13+
this.store.isNodeDraggable = isNodeDraggable
14+
this.store.isNodeDroppable = isNodeDroppable
1315
if (this.isRoot || this.data.isDragPlaceHolder) {
1416
return
1517
}
@@ -22,6 +24,7 @@ export default {
2224
getEl: () => this.$el,
2325
minTranslate: 10,
2426
drag: (e, opt, store) => {
27+
autoMoveDragPlaceHolder.dragStart()
2528
// this store is not tree
2629
const draggableHelperInfo = {event: e, options: opt, store}
2730
if (this.store.ondragstart && this.store.ondragstart(this.data, draggableHelperInfo) === false) {
@@ -30,14 +33,14 @@ export default {
3033
if (!isNodeDraggable(this.data)) {
3134
return false
3235
}
36+
this.store.$emit('drag', this.data)
3337
// record start positon
3438
const siblings = this.data.parent.children
3539
this.startPosition = {siblings, index: siblings.indexOf(this.data)}
3640
//
3741
dplh.innerStyle.height = store.el.offsetHeight + 'px'
3842
th.insertAfter(dplh, this.data)
3943
this.data.class += ' dragging'
40-
this.store.$emit('drag', this.data)
4144
// console.log('drag start');
4245
},
4346
moving: (e, opt, store) => {
@@ -82,12 +85,4 @@ export default {
8285
},
8386
}
8487
85-
function isNodeDraggable(node, nodeVm) {
86-
if (node.hasOwnProperty('draggable')) {
87-
return node.draggable
88-
} else {
89-
return true
90-
}
91-
}
92-
9388
</script>

src/components/Tree.vue

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
.he-tree.tree
33
TreeNode(:data="rootData" :store="store")
44
template(slot-scope="props")
5-
slot(:data="props.data" :store="store")
5+
slot(:data="props.data" :store="store" :vm="props.vm")
66
</template>
77

88
<script>
@@ -35,7 +35,7 @@ export default {
3535
return
3636
}
3737
// make rootData always use a same object
38-
this.rootData = this.rootData || {isRoot: true, _id: `tree_${this._uid}_node_root`, level: 0}
38+
this.rootData = this.rootData || {isRoot: true, _id: `tree_${this._uid}_node_root`}
3939
th.breadthFirstSearch(data, (node, k, parent) => {
4040
this.compeleteNode(node, parent)
4141
})
@@ -62,28 +62,18 @@ export default {
6262
}
6363
}
6464
this.$set(node, 'parent', parent || this.rootData)
65-
this.$set(node, 'level', node.parent.level + 1)
6665
if (!node.hasOwnProperty('_id')) {
6766
node._id = `tree_${this._uid}_node_${hp.strRand(this.idLength)}`
6867
}
6968
node._treeNodePropertiesCompleted = true
7069
},
71-
updateBranchLevel(branch, startLevel = branch.parent.level + 1) {
72-
branch.level = startLevel
73-
if (branch.children && branch.children.length > 0) {
74-
th.breadthFirstSearch(branch.children, (node, i, p) => {
75-
node.level = node.parent.level + 1
76-
})
77-
}
78-
},
7970
// pure node self
80-
pure(node, withChildren) {
71+
pure(node, withChildren, after) {
8172
const t = Object.assign({}, node)
8273
delete t._id
8374
delete t.parent
8475
delete t.children
8576
delete t.open
86-
delete t.level
8777
delete t.active
8878
delete t.style
8979
delete t.class
@@ -102,6 +92,9 @@ export default {
10292
t.children[k] = this.pure(v, withChildren)
10393
})
10494
}
95+
if (after) {
96+
return after(t, node) || t
97+
}
10598
return t
10699
},
107100
getNodeById(id) {
@@ -164,8 +157,8 @@ export default {
164157
this.openNode(node, closeOld)
165158
}
166159
},
167-
getPureData() {
168-
return this.pure(this.rootData, true).children
160+
getPureData(after) {
161+
return this.pure(this.rootData, true, after).children
169162
},
170163
deleteNode(node) {
171164
return hp.arrayRemove(node.parent.children, node)

src/components/TreeNode.vue

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
<template lang="pug">
22
.tree-node(
33
:class="[data.active ? store.activatedClass : '', data.open ? store.openedClass : '', data.class]"
4-
:id="data._id" :data-level="data.level"
4+
:style="data.style"
5+
:id="data._id"
56
)
67
.tree-node-inner-back(v-if="!isRoot" :style="[innerBackStyle, data.innerBackStyle]" :class="[data.innerBackClass]")
78
.tree-node-inner(:style="[data.innerStyle]" :class="[data.innerClass]")
8-
slot(:data="data" :store="store")
9+
slot(:data="data" :store="store" :vm="vm")
910
.tree-node-children(v-if="childrenVisible")
1011
TreeNode(v-for="child in data.children" :key="child._id"
11-
:data="child" :store="store"
12+
:data="child" :store="store" :level="childrenLevel"
1213
)
1314
template(slot-scope="props")
14-
slot(:data="props.data" :store="props.store")
15+
slot(:data="props.data" :store="props.store" :vm="props.vm")
1516
</template>
1617
<script>
1718
import * as th from 'tree-helper'
@@ -21,13 +22,18 @@ export default {
2122
props: {
2223
data: {},
2324
store: {},
25+
level: {default: 0}, // readonly
26+
},
27+
data() {
28+
return {
29+
vm: this,
30+
}
2431
},
25-
// data() {
26-
// return {
27-
// }
28-
// },
2932
computed: {
30-
isRoot() {return this.data.level === 0},
33+
childrenLevel() {
34+
return this.level + 1
35+
},
36+
isRoot() {return this.data.isRoot},
3137
childrenVisible() {
3238
const {data} = this
3339
return this.isRoot || data.children && data.children.length && data.open
@@ -36,9 +42,8 @@ export default {
3642
const r = {
3743
marginBottom: this.store.space + 'px'
3844
}
39-
if (!this.isRoot && this.data.level > 1) {
40-
const {indentType} = this.store
41-
r.paddingLeft = (this.data.level - 1) * this.store.indent + 'px'
45+
if (!this.isRoot && this.level > 1) {
46+
r.paddingLeft = (this.level - 1) * this.store.indent + 'px'
4247
}
4348
return r
4449
},
@@ -49,22 +54,12 @@ export default {
4954
handler(data) {
5055
if (data) {
5156
data._vm = this
52-
// the level of root is 0, no need to update root level
5357
if (!data._treeNodePropertiesCompleted && !data.isRoot) {
54-
// this.store.compeleteNode(data, this.$parent.data)
55-
th.breadthFirstSearch(data, (node, k, parent) => { this.store.compeleteNode(node, parent) })
58+
this.store.compeleteNode(data, this.$parent.data)
5659
}
5760
}
5861
}
5962
},
60-
'data.parent': {
61-
immediate: true,
62-
handler(parent, old) {
63-
if (parent !== old) {
64-
this.store.updateBranchLevel(this.data)
65-
}
66-
}
67-
}
6863
},
6964
// methods: {},
7065
// created() {},

0 commit comments

Comments
 (0)