Skip to content

Commit 169e1e6

Browse files
committed
recontructing, plugin fold and check done
1 parent e311e8d commit 169e1e6

File tree

8 files changed

+278
-291
lines changed

8 files changed

+278
-291
lines changed

src/App.vue

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,22 @@
22
<template lang="pug">
33
#app
44
BaseTree.mr
5-
TestTree.mr
6-
IDModeTree.mr
7-
NodeBackTree.mr
8-
DraggableProTree.mr
5+
//- TestTree.mr
6+
//- IDModeTree.mr
7+
//- NodeBackTree.mr
8+
//- DraggableProTree.mr
99
</template>
1010

1111
<script>
1212
import BaseTree from '@/examples/Base'
1313
import TestTree from '@/examples/Test'
1414
import IDModeTree from '@/examples/IDMode'
1515
import NodeBackTree from '@/examples/NodeBack'
16-
import DraggableProTree from '@/examples/DraggablePro'
16+
// import DraggableProTree from '@/examples/DraggablePro'
1717
1818
export default {
19-
components: {BaseTree, TestTree, IDModeTree, NodeBackTree, DraggableProTree},
19+
// components: {BaseTree, TestTree, IDModeTree, NodeBackTree, DraggableProTree},
20+
components: {BaseTree, TestTree, IDModeTree, NodeBackTree},
2021
// data() {
2122
// return {}
2223
// },
@@ -32,6 +33,9 @@ export default {
3233
#app{
3334
display: flex;
3435
}
36+
.ml{
37+
margin-left: 1em;
38+
}
3539
.mr{
3640
margin-right: 1em;
3741
}

src/components/Tree.vue

Lines changed: 67 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -1,187 +1,93 @@
1-
<template lang="pug">
2-
.tree-children(:class="{'he-tree tree-root': isRoot}" :data-tree-id="_uid")
3-
.tree-branch(v-for="(node, i) in nodes" :key="metas[i].id" :id="metas[i].DOMId")
4-
.tree-node()
5-
slot(:node="node" :meta="metas[i]" :root="root") {{node.text}}
6-
transition(v-if="node.children && node.children.length > 0" :name="root.foldingTransition")
7-
Tree(v-if="!metas[i].folded" :value="node.children" :privateProps="{...childPrivateProps, parent: node}")
8-
template(slot-scope="props")
9-
slot(:node="props.node" :meta="props.meta" :root="props.root") {{node.text}}
10-
</template>
11-
121
<script>
132
import * as hp from 'helper-js'
143
import * as th from 'tree-helper'
154
import * as tdhp from '@/todo-utils'
165
6+
const template = function (h) {
7+
const treeTpl = (nodes, isRoot, parentPath) => {
8+
const branchTpl = (node, index) => {
9+
const path = [...parentPath, index]
10+
const slotDefault = () => {
11+
if (this.$scopedSlots.default) {
12+
return this.$scopedSlots.default({node, index, path, store: this})
13+
} else if (this.$slots.default) {
14+
return this.$slots.default
15+
} else {
16+
return node.text
17+
}
18+
}
19+
return <div class="tree-branch" data-tree-node-path={path.join(',')}>
20+
<div class="tree-node">{slotDefault()}</div>
21+
{(node.children && node.children.length) > 0 && <transition name={this.$props.foldingTransition}>
22+
{!node.$folded && treeTpl(node.children, false, path)}
23+
</transition>}
24+
</div>
25+
}
26+
return <div class={`${isRoot ? 'he-tree tree-root' : ''} tree-children`} data-tree-id={isRoot ? this._uid : false}>
27+
{nodes.map(branchTpl)}
28+
</div>
29+
}
30+
return treeTpl(this.value, true, [])
31+
}
32+
1733
const trees = {}
1834
1935
const Tree = {
20-
name: 'Tree',
36+
render: template,
2137
props: {
2238
value: {},
23-
privateProps: {},
24-
idMode: {default: 'object'}, // object, id(node must has id)
25-
dataModification: {default: 'modify_old'}, // new, modify_old. create new data or modify old
26-
DOM_ID_PREFIX: {default: 'he_tree'},
2739
},
2840
// components: {},
2941
data() {
3042
return {
31-
metas: [], // metas of current level nodes
3243
trees,
3344
}
3445
},
35-
computed: {
36-
root() { return this.privateProps && this.privateProps.root || this },
37-
isRoot() { return this.root === this },
38-
level() { return this.privateProps ? this.privateProps.level : 1 },
39-
parent() { return this.privateProps && this.privateProps.parent },
40-
nodes() { return this.value || [] },
41-
childPrivateProps() {
42-
return {
43-
root: this.root,
44-
level: this.level + 1,
45-
}
46-
},
47-
},
48-
watch: {},
46+
// computed: {},
47+
// watch: {},
4948
methods: {
50-
nodesWatcher(nodes, oldNodes) {
51-
if (oldNodes) {
52-
// removed metas
53-
if (this.root.idMode === 'id') {
54-
const t = {}
55-
nodes.forEach(node => {t[node.id]=true})
56-
oldNodes.forEach(node => {
57-
if (!t[node.id]) {
58-
// delete node and children meta
59-
th.depthFirstSearch(node, (childNode) => {
60-
delete this.root.metaMap[childNode.id]
61-
delete this.root.idMap[childNode.id]
62-
})
63-
}
64-
})
65-
} else {
66-
const t = new Map()
67-
nodes.forEach(node => t.set(node, null))
68-
oldNodes.forEach(node => {
69-
if (!t.has(node)) {
70-
// delete node and children meta
71-
th.depthFirstSearch(node, (childNode) => {
72-
const meta = this.root.metaMap.get(childNode)
73-
this.root.metaMap.delete(childNode)
74-
delete this.root.idMap[meta.id]
75-
})
76-
}
77-
})
78-
}
79-
}
80-
//
81-
this.metas = nodes.map(node => {
82-
const oldMeta = this.idMode === 'id' ? this.root.metaMap[node.id] : this.root.metaMap.get(node)
83-
const newMeta = {}
84-
// initial meta
85-
if (node.$meta) {
86-
Object.assign(newMeta, node.$meta)
87-
}
88-
//
89-
let id, DOMId
90-
if (oldMeta) {
91-
id = oldMeta.id
92-
DOMId = oldMeta.DOMId
93-
} else {
94-
id = node.id || hp.strRand()
95-
DOMId = `${this.DOM_ID_PREFIX}_${this.root._uid}_branch_${id}`
96-
}
97-
Object.assign(newMeta, {
98-
id,
99-
DOMId,
100-
})
101-
if (this.$options._afterMetaCreateds) {
102-
for (const func of this.$options._afterMetaCreateds) {
103-
func.call(this, newMeta, node)
104-
}
105-
}
106-
if (oldMeta) {
107-
Object.assign(newMeta, oldMeta)
108-
}
109-
Object.assign(newMeta, {
110-
parent: this.parent,
111-
level: this.level,
112-
})
113-
if (this.idMode === 'id') {
114-
this.root.metaMap[id] = newMeta
115-
} else {
116-
this.root.metaMap.set(node, newMeta)
117-
}
118-
this.root.idMap[id] = node
119-
return newMeta
120-
})
121-
},
122-
getMetaByNode(node) {
123-
return this.root.idMode === 'id' ? this.root.metaMap[node.id] : this.root.metaMap.get(node)
124-
},
125-
convertDOMIDToID(DOMId) {
126-
let r = DOMId
127-
if (DOMId.startsWith(this.DOM_ID_PREFIX)) {
128-
r = DOMId.split('_branch_')[1]
129-
}
130-
return r
131-
},
132-
// by DOMId or ID
133-
getNodeByID(DOMIdOrID) {
134-
const id = this.convertDOMIDToID(DOMIdOrID)
135-
return this.root.idMap[id]
136-
},
137-
getMetaByID(DOMIdOrID) {
138-
const node = this.getNodeByID(DOMIdOrID)
139-
return this.getMetaByNode(node)
140-
},
141-
getNodeParent(node) {
142-
const meta = this.getMetaByNode(node)
143-
return meta ? meta.parent : null
144-
},
145-
getNodeSiblings(node, opt = {}) {
146-
opt = {
147-
convertToArray: true,
148-
...opt,
149-
}
150-
const parent = this.getNodeParent(node)
151-
let r = parent ? parent.children : this.root.value
152-
if (opt.convertToArray) {
153-
r = hp.toArrayIfNot(r)
154-
}
155-
return r
156-
},
157-
* iterateParents(node, opt = {}) {
158-
if (opt.withSelf) {
159-
yield node
160-
}
161-
let cur = this.getNodeParent(node)
162-
while (cur) {
163-
yield cur
164-
cur = this.getNodeParent(cur)
165-
}
166-
},
49+
// * iterateParents(node, opt = {}) {
50+
// if (opt.withSelf) {
51+
// yield node
52+
// }
53+
// let cur = this.getNodeParent(node)
54+
// while (cur) {
55+
// yield cur
56+
// cur = this.getNodeParent(cur)
57+
// }
58+
// },
16759
traverseDescendants(nodeOrNodes, handler) {
16860
return th.depthFirstSearch(nodeOrNodes, handler)
16961
},
170-
cloneTreeData(nodeOrNodes) {
171-
const nodes = hp.toArrayIfNot(nodeOrNodes)
172-
const walk = (arr) => arr.map(node => {
173-
const newNode = Object.assign({}, node)
174-
if (newNode.children) {
175-
newNode.children = walk(newNode.children)
176-
}
177-
return newNode
178-
})
179-
let r = walk(nodes)
180-
return hp.isArray(nodeOrNodes) ? r : r[0]
181-
},
62+
// cloneTreeData(nodeOrNodes) {
63+
// const nodes = hp.toArrayIfNot(nodeOrNodes)
64+
// const walk = (arr) => arr.map(node => {
65+
// const newNode = Object.assign({}, node)
66+
// if (newNode.children) {
67+
// newNode.children = walk(newNode.children)
68+
// }
69+
// return newNode
70+
// })
71+
// let r = walk(nodes)
72+
// return hp.isArray(nodeOrNodes) ? r : r[0]
73+
// },
18274
getTreeVmByTreeEl(treeEl) {
18375
return this.root.trees[treeEl.getAttribute('data-tree-id')]
18476
},
77+
getNodeByPath(path) {
78+
return hp.arrayLast(this.getAllNodesByPath(path))
79+
},
80+
getAllNodesByPath(path) {
81+
let nodes = []
82+
let cur
83+
let curChildren = this.value
84+
for (const index of path) {
85+
cur = curChildren[index]
86+
nodes.push(cur)
87+
curChildren = cur.children
88+
}
89+
return nodes
90+
},
18591
// todo extract hooks to vue-functions
18692
// get hooks in this._hooks, without which in props
18793
_getNonPropHooksByName(name) {
@@ -221,22 +127,7 @@ const Tree = {
221127
}
222128
},
223129
},
224-
created() {
225-
if (this === this.root) {
226-
this.metaMap = this.idMode === 'id' ? {} : new Map()
227-
this.idMap = {}
228-
this.trees[this._uid] = this
229-
this.$once('hook:beforeDestroy', () => {
230-
this.$delete(this.trees, this._uid)
231-
})
232-
}
233-
this.$watch('nodes', this.nodesWatcher, {immediate: true})
234-
this.$watch('level', (level, oldLevel) => {
235-
for (const node of this.nodes) {
236-
this.getMetaByNode(node).level = level
237-
}
238-
}, {immediate: true})
239-
},
130+
// created() {},
240131
// mounted() {},
241132
// beforeDestroy() {},
242133

src/examples/Base.vue

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@
33
div
44
h2 Base
55
.base-trees
6-
Tree.base-tree(:value="treeData1" unfoldAllAtBeginning ref="tree")
7-
div(slot-scope="{node, meta, root}")
8-
b(v-if="node.children && node.children.length > 0" @click="root.toggleFold(node)") {{meta.folded ? '+' : '-'}}&nbsp;
9-
input(type="checkbox" v-model="meta.checked" @change="root.afterCheckChanged(node)")
6+
Tree.base-tree(:value="treeData1" unfoldAllAtBeginning ref="tree1")
7+
//- div(slot-scope="{node, index}") {{node}}
8+
Tree.base-tree.ml(:value="treeData1" unfoldAllAtBeginning ref="tree2")
9+
div(slot-scope="{node, index, path, store}")
10+
b(v-if="node.children && node.children.length > 0" @click="store.toggleFold(node, path)") {{node.$folded ? '+' : '-'}}&nbsp;
11+
input(type="checkbox" v-model="node.$checked" @change="store.toggleCheck(node, path)")
1012
| &nbsp;
1113
span {{node.text}}
12-
Tree.base-tree.base-tree2(:value="treeData2" unfoldAllAtBeginning ref="tree")
13-
div(slot-scope="{node, meta, root}")
14-
b(v-if="node.children && node.children.length > 0" @click="root.toggleFold(node)") {{meta.folded ? '+' : '-'}}&nbsp;
15-
input(type="checkbox" v-model="meta.checked" @change="root.afterCheckChanged(node)")
16-
| &nbsp;
17-
span {{node.text}}
18-
div(style="position: fixed;width: 400px;height: 200px;background: teal;opacity: 0.2;display: flex;justify-content: center;align-items: center;font-size: 40px;color: #fffc;") MASK
14+
//- Tree.base-tree.base-tree2(:value="treeData2" unfoldAllAtBeginning ref="tree3")
15+
//- div(slot-scope="{node, meta, root}")
16+
//- b(v-if="node.children && node.children.length > 0" @click="root.toggleFold(node)") {{meta.folded ? '+' : '-'}}&nbsp;
17+
//- input(type="checkbox" v-model="meta.checked" @change="root.afterCheckChanged(node)")
18+
//- | &nbsp;
19+
//- span {{node.text}}
20+
//- div(style="position: fixed;width: 400px;height: 200px;background: teal;opacity: 0.2;display: flex;justify-content: center;align-items: center;font-size: 40px;color: #fffc;") MASK
1921
</template>
2022

2123
<script>

0 commit comments

Comments
 (0)