Skip to content

Commit 9aee069

Browse files
committed
Tree ui base done (meta out of data)
1 parent b7a5721 commit 9aee069

File tree

2 files changed

+69
-149
lines changed

2 files changed

+69
-149
lines changed

src/components/Tree.vue

Lines changed: 64 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,171 +1,91 @@
11
<template lang="pug">
22
.he-tree.tree
3-
.tree-branch(v-for="node in data" :class="[data.open ? root.openedClass : '']")
4-
slot(:data="node" :root="root")
3+
.tree-branch(v-for="(node, i) in nodes" :key="metas[i].id" :class="[metas[i].folded ? root.foldedClass : root.unfoldedClass]")
4+
slot(:node="node" :meta="metas[i]" :root="root")
55
.tree-node {{node.text}}
6-
transition(:name="root.childrenTransition")
7-
Tree.tree-children(v-if="node.open" :data="node.children" :root="root")
6+
transition(v-if="node.children && node.children.length > 0" :name="root.foldingTransition")
7+
Tree.tree-children(v-if="!metas[i].folded" :value="node.children" :privateProps="childPrivateProps")
88
</template>
99

1010
<script>
1111
import * as hp from 'helper-js'
1212
import * as th from 'tree-helper'
1313
1414
export default {
15+
name: 'Tree',
1516
props: {
16-
data: {},
17-
root: {default: is => this},
18-
openedClass: {default: 'open'},
19-
childrenTransition: {},
17+
value: {},
18+
foldedClass: {default: 'folded'},
19+
unfoldedClass: {default: 'unfolded'},
20+
foldingTransition: {},
21+
foldAllAtBeginning: {type: Boolean},
22+
privateProps: {},
23+
idMode: {default: 'object'}, // object, id(node must has id)
2024
},
2125
// components: {},
2226
data() {
2327
return {
24-
// rootData: null,
28+
metas: [], // metas of current level nodes
2529
}
2630
},
27-
// computed: {},
28-
watch: {
29-
// data: {
30-
// immediate: true,
31-
// handler(data, old) {
32-
// if (data === old) {
33-
// return
34-
// }
35-
// // make rootData always use a same object
36-
// this.rootData = this.rootData || {isRoot: true, _id: `tree_${this._uid}_node_root`, children: []}
37-
// th.breadthFirstSearch(data, (node, k, parent) => {
38-
// this.compeleteNode(node, parent)
39-
// })
40-
// this.rootData.children = data
41-
// }
42-
// }
43-
},
44-
methods: {
45-
compeleteNode(node, parent) {
46-
const compeletedData = {
47-
open: true,
48-
children: [],
49-
active: false,
50-
style: {},
51-
class: '',
52-
innerStyle: {},
53-
innerClass: '',
54-
innerBackStyle: {},
55-
innerBackClass: {},
56-
}
57-
for (const key in compeletedData) {
58-
if (!node.hasOwnProperty(key)) {
59-
this.$set(node, key, compeletedData[key])
60-
}
31+
computed: {
32+
root() { return this.privateProps && this.privateProps.root || this },
33+
nodes() { return this.value || [] },
34+
childPrivateProps() {
35+
return {
36+
root: this.root
6137
}
62-
this.$set(node, 'parent', parent || this.rootData)
63-
if (!node.hasOwnProperty('_id')) {
64-
node._id = `tree_${this._uid}_node_${hp.strRand(this.idLength)}`
65-
}
66-
node._treeNodePropertiesCompleted = true
6738
},
68-
// pure node self
69-
pure(node, withChildren, after) {
70-
const t = Object.assign({}, node)
71-
delete t._id
72-
delete t.parent
73-
delete t.children
74-
delete t.open
75-
delete t.active
76-
delete t.style
77-
delete t.class
78-
delete t.innerStyle
79-
delete t.innerClass
80-
delete t.innerBackStyle
81-
delete t.innerBackClass
82-
for (const key of Object.keys(t)) {
83-
if (key[0] === '_') {
84-
delete t[key]
39+
},
40+
watch: {},
41+
methods: {
42+
nodesWatcher(nodes, oldNodes) {
43+
if (oldNodes) {
44+
// removed metas
45+
if (this.root.idMode === 'id') {
46+
const t = {}
47+
nodes.forEach(node => {t[node.id]=true})
48+
oldNodes.forEach(node => {
49+
if (!t[node.id]) {
50+
// delete node and children meta
51+
th.depthFirstSearch(node, (childNode) => {
52+
delete this.root.metaMap[childNode.id]
53+
})
54+
}
55+
})
56+
} else {
57+
const t = new Map()
58+
nodes.forEach(node => t.set(node, null))
59+
oldNodes.forEach(node => {
60+
if (!t.has(node)) {
61+
// delete node and children meta
62+
th.depthFirstSearch(node, (childNode) => {
63+
this.root.metaMap.delete(childNode)
64+
})
65+
}
66+
})
8567
}
8668
}
87-
if (withChildren && node.children) {
88-
t.children = node.children.slice()
89-
t.children.forEach((v, k) => {
90-
t.children[k] = this.pure(v, withChildren)
91-
})
92-
}
93-
if (after) {
94-
return after(t, node) || t
95-
}
96-
return t
97-
},
98-
getNodeById(id) {
99-
let r
100-
th.breadthFirstSearch(this.rootData.children, (node) => {
101-
if (node._id === id) {
102-
r = node
103-
return false
104-
}
105-
})
106-
return r
107-
},
108-
getActivated() {
109-
const r = []
110-
th.breadthFirstSearch(this.rootData.children, (node) => {
111-
if (node.active) {
112-
r.push(node)
113-
}
69+
//
70+
this.metas = nodes.map(node => (this.idMode === 'id' ? this.root.metaMap[node.id] : this.root.metaMap.get(node)) || {
71+
id: `he_tree_node_${node.id || hp.strRand()}`,
72+
folded: this.root.foldAllAtBeginning,
11473
})
115-
return r
116-
},
117-
getOpened() {
118-
const r = []
119-
th.breadthFirstSearch(this.rootData.children, (node) => {
120-
if (node.open) {
121-
r.push(node)
122-
}
123-
})
124-
return r
125-
},
126-
activeNode(node, inactiveOld) {
127-
let {activated} = this
128-
if (inactiveOld) {
129-
this.getActivated().forEach(node2 => {
130-
node2.active = false
131-
})
132-
}
133-
node.active = true
134-
},
135-
toggleActive(node, inactiveOld) {
136-
if (node.active) {
137-
node.active = false
138-
} else {
139-
this.activeNode(node, inactiveOld)
140-
}
141-
},
142-
openNode(node, closeOld) {
143-
let {opened} = this
144-
if (closeOld) {
145-
this.getOpened().forEach(node2 => {
146-
node2.open = false
147-
this.$emit('nodeOpenChanged', node2)
148-
})
149-
}
150-
node.open = true
151-
this.$emit('nodeOpenChanged', node)
152-
},
153-
toggleOpen(node, closeOld) {
154-
if (node.open) {
155-
node.open = false
156-
this.$emit('nodeOpenChanged', node)
157-
} else {
158-
this.openNode(node, closeOld)
159-
}
160-
},
161-
getPureData(after) {
162-
return this.pure(this.rootData, true, after).children
163-
},
164-
deleteNode(node) {
165-
return hp.arrayRemove(node.parent.children, node)
16674
},
16775
},
168-
// created() {},
76+
created() {
77+
if (this === this.root) {
78+
this.metaMap = this.idMode === 'id' ? {} : new Map()
79+
}
80+
this.$watch('nodes', (...args) => this.nodesWatcher(...args), {immediate: true})
81+
},
16982
// mounted() {},
83+
// beforeDestroy() {},
17084
}
17185
</script>
86+
87+
<style>
88+
.he-tree .tree-children{
89+
padding-left: 20px;
90+
}
91+
</style>

src/examples/Base.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
<template lang="pug">
33
div
44
h2 Base
5-
Tree(:data="originalData" draggable crossTree ref="tree1" @change="tree1Change")
6-
div(slot-scope="{data, store}")
7-
b(v-if="data.children && data.children.length" @click="store.toggleOpen(data)") {{data.open ? '-' : '+'}}&nbsp;
8-
span {{data.text}}
5+
Tree(:value="originalData" foldAllAtBeginning)
6+
div(slot-scope="{node, meta, root}")
7+
b(v-if="node.children && node.children.length > 0" @click="meta.folded=!meta.folded") {{meta.folded ? '+' : '-'}}&nbsp;
8+
span {{node.text}}
99
</template>
1010

1111
<script>
12-
import Tree from '@/components/DraggableTree'
12+
import Tree from '@/components/Tree'
1313
export default {
1414
components: {Tree},
1515
data() {

0 commit comments

Comments
 (0)