Skip to content

Commit c58f9d7

Browse files
authored
add rendered field to item to solve first aspect of #24
2 parents 5407c8f + 7c0838c commit c58f9d7

File tree

7 files changed

+87
-75
lines changed

7 files changed

+87
-75
lines changed

README.md

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
# vue-tree
22

3+
[![Master Build](https://travis-ci.com/eidng8/vue-tree.svg?branch=master)](https://travis-ci.com/eidng8/vue-tree)
4+
[![Master Coverage](https://coveralls.io/repos/github/eidng8/vue-tree/badge.svg?branch=master)](https://coveralls.io/github/eidng8/vue-tree?branch=master)
5+
36
A Vue.js tree view component with stable DOM tree. By stable, it means the
47
DOM structure will not change once it is rendered.
58

69

7-
## Master Branch
8-
[![Build](https://travis-ci.com/eidng8/vue-tree.svg?branch=master)](https://travis-ci.com/eidng8/vue-tree)
9-
[![Coverage](https://coveralls.io/repos/github/eidng8/vue-tree/badge.svg?branch=master)](https://coveralls.io/github/eidng8/vue-tree?branch=master)
10-
11-
## Dev Branch
12-
[![Build](https://travis-ci.com/eidng8/vue-tree.svg?branch=dev)](https://travis-ci.com/eidng8/vue-tree)
13-
[![Coverage](https://coveralls.io/repos/github/eidng8/vue-tree/badge.svg?branch=dev)](https://coveralls.io/github/eidng8/vue-tree?branch=dev)
14-
15-
1610
## Performance Consideration
1711

1812
The DOM structure of this component doesn't change once rendered.

package.json

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"name": "g8-vue-tree",
3-
"version": "0.0.21",
3+
"version": "0.0.22",
44
"repository": "git@github.com:eidng8/vue-tree.git",
55
"bugs": "git@github.com:eidng8/vue-tree/issues",
6-
"author": "eidng8 <cheung.jackey@gmail.com>",
6+
"author": "eidng8",
77
"license": "GPL-3.0",
88
"main": "./dist/g8-vue-tree.umd.min.js",
99
"typings": "./typings/index.d.ts",
@@ -14,12 +14,17 @@
1414
"/src/components",
1515
"/typings"
1616
],
17+
"keywords": [
18+
"typescript",
19+
"vue"
20+
],
1721
"scripts": {
1822
"build": "vue-cli-service build --target lib --mode production ./src/index.ts",
1923
"serve": "vue-cli-service serve",
2024
"start": "npm run serve",
2125
"test": "npm run test:unit && npm run test:e2e",
2226
"test:unit": "vue-cli-service test:unit",
27+
"test:cover": "npm run test:unit -- --coverage",
2328
"test:e2e": "vue-cli-service test:e2e --headless",
2429
"test:e2e:visual": "vue-cli-service test:e2e",
2530
"lint": "vue-cli-service lint"

src/App.vue

+31-32
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
<template>
88
<div id="app">
9+
<button @click="populate()">populate tree</button>
910
<ul class="g8-tree-view g8-tree__highlight_hover">
1011
<g8-tree-view
1112
checker="1"
@@ -25,7 +26,7 @@
2526

2627
<script lang="ts">
2728
import {Component, Vue} from 'vue-property-decorator';
28-
import {G8TreeView, G8TreeItem} from './';
29+
import {G8TreeItem, G8TreeView} from './';
2930

3031
@Component({
3132
components: {
@@ -35,37 +36,7 @@ import {G8TreeView, G8TreeItem} from './';
3536
export default class App extends Vue {
3637
item: G8TreeItem = {
3738
key: 'root',
38-
name: 'root name',
39-
tags: [{key: 'root tag', label: 'root label'}],
40-
children: [
41-
{
42-
key: 'item-1',
43-
name: 'item 1',
44-
tags: [
45-
{key: 1, label: 'tag1.1'},
46-
{key: 1, label: 'tag1.2', hint: '2nd tag in the 2nd branch'},
47-
],
48-
},
49-
{
50-
key: 'item-2',
51-
name: 'item 2',
52-
tags: [{key: 2, label: 'tag1.1'}],
53-
children: [
54-
{
55-
key: 'item-2.1',
56-
name: 'item 2.1',
57-
tags: [
58-
{key: '2.1.1', label: 'tag2.1.1'},
59-
{key: '2.1.2', label: 'tag2.1.2'},
60-
],
61-
},
62-
{
63-
key: 'item-2.2',
64-
name: 'item 2.2',
65-
},
66-
],
67-
},
68-
],
39+
name: 'Click the button above to populate me.',
6940
};
7041

7142
itemClicked = '';
@@ -75,6 +46,34 @@ export default class App extends Vue {
7546
tagClicked = '';
7647

7748
tagDblClicked = '';
49+
50+
populate() {
51+
const total = 1000;
52+
this.item = {
53+
key: 'root',
54+
name: 'root name',
55+
tags: [{key: 'root tag', label: 'root label'}],
56+
children: [],
57+
};
58+
for (let i = 1; i < total; i++) {
59+
const child: G8TreeItem = {
60+
key: `key-${i}`,
61+
name: `name ${i}`,
62+
tags: [{key: `tag-${i}`, label: `tag ${i}`}],
63+
children: [],
64+
};
65+
for (let j = 1; j < total; j++) {
66+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
67+
child.children!.push({
68+
key: `key-${i}.${j}`,
69+
name: `name ${i}.${j}`,
70+
tags: [{key: `tag-${i}.${j}`, label: `tag ${i}.${j}`}],
71+
});
72+
}
73+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
74+
this.item.children!.push(child);
75+
}
76+
}
7877
}
7978
</script>
8079

src/components/G8TreeView.vue

+7-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
>{{ tag.label }}</label>
2727
</span>
2828
</div>
29-
<ul v-if="hasChild" class="g8-tree__branch">
29+
<ul v-if="expanded || item.rendered" class="g8-tree__branch">
3030
<g8-tree-view v-for="(child, index) in item.children"
3131
:key="index"
3232
:item="child"
@@ -45,9 +45,7 @@
4545
import {Component, Prop, Vue} from 'vue-property-decorator';
4646
import {G8StateChangeEvent, G8TreeItem} from './types';
4747

48-
@Component({
49-
name: 'g8-tree-view',
50-
})
48+
@Component({name: 'g8-tree-view'})
5149
export default class G8TreeView extends Vue {
5250
@Prop() item!: G8TreeItem;
5351

@@ -67,6 +65,10 @@ export default class G8TreeView extends Vue {
6765
return this.item.children && this.item.children.length;
6866
}
6967

68+
created() {
69+
// console.log(`created: ${this.item.name}`);
70+
}
71+
7072
setState(state: boolean) {
7173
this.item.checked = this.checked = state;
7274
this.$children.forEach(c => (c as G8TreeView).setState(state));
@@ -75,6 +77,7 @@ export default class G8TreeView extends Vue {
7577

7678
clicked() {
7779
if (this.hasChild) {
80+
this.item.rendered = true;
7881
this.expanded = !this.expanded;
7982
}
8083
this.$emit('click', this.item.key);

src/components/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ export interface G8TreeItem {
1717
*/
1818
ints?: boolean;
1919

20+
rendered?: boolean;
21+
2022
tags?: G8TreeItemTag[];
2123

2224
children?: G8TreeItem[];

tests/e2e/specs/test.js

+15-6
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,17 @@ module.exports = {
1818
.assert // the tree view is rendered
1919
.elementPresent('.g8-tree-view')
2020
.assert // the root node's text is correct
21-
.containsText('.g8-tree__node_label_text', 'root name')
21+
.containsText(
22+
'.g8-tree__node_label_text',
23+
'Click the button above to populate me.',
24+
)
2225

26+
.click('button')
27+
.assert // root node's text has changed
28+
.containsText(
29+
'.g8-tree__node_label_text',
30+
'root name',
31+
)
2332
.click(rootLabel)
2433
.assert // clicking the toggle expands the root
2534
.cssClassPresent(root, 'g8-tree__node_expended')
@@ -30,7 +39,7 @@ module.exports = {
3039
.assert // clicking the toggle expands the first branch
3140
.elementPresent('.g8-tree__branch .g8-tree__node_expended')
3241
.assert // click event is fired
33-
.value('#itemClicked', 'item-2')
42+
.value('#itemClicked', 'key-2')
3443
.moveToElement(rootLabel, 1, 1)
3544
.doubleClick()
3645
.assert // double clicking won't collapse the node
@@ -40,18 +49,18 @@ module.exports = {
4049

4150
.click(`${leaf} .g8-tree__node_label`)
4251
.assert // click event is fired
43-
.value('#itemClicked', 'item-2.1')
52+
.value('#itemClicked', 'key-2.1')
4453
.moveToElement(`${leaf} .g8-tree__node_label`, 1, 1)
4554
.doubleClick()
4655
.assert // click event is fired
47-
.value('#itemDblClicked', 'item-2.1')
56+
.value('#itemDblClicked', 'key-2.1')
4857
.click(`${leaf} .g8-tree__node_tag:last-child`)
4958
.assert // click event is fired
50-
.value('#tagClicked', 'item-2.1,2.1.2,1')
59+
.value('#tagClicked', 'key-2.1,tag-2.1,0')
5160
.moveToElement(`${leaf} .g8-tree__node_tag`, 1, 1)
5261
.doubleClick()
5362
.assert // click event is fired
54-
.value('#tagDblClicked', 'item-2.1,2.1.1,0')
63+
.value('#tagDblClicked', 'key-2.1,tag-2.1,0')
5564

5665
.click(rootLabel)
5766
.assert.not // clicking the toggle collapses the node

tests/unit/G8TreeView.spec.ts

+22-22
Original file line numberDiff line numberDiff line change
@@ -78,34 +78,34 @@ describe('Tree View', () => {
7878
.toBe('tag2');
7979
});
8080

81-
it('renders hierarchy', async () => {
82-
expect.assertions(4);
83-
const wrapper = mount(G8TreeView, {propsData: tree});
84-
expect(wrapper.props('item')).toEqual(tree.item);
85-
const labels = wrapper.findAll('.g8-tree__node_label_text');
86-
expect(labels.length).toBe(5);
87-
expect(labels.at(0).text()).toBe('root name');
88-
expect(labels.at(1).text()).toBe('item 1');
89-
});
90-
91-
it('expends/collapses branches on click', async () => {
92-
expect.assertions(5);
93-
// initially no branch were expanded
81+
it('expends/collapses and renders branches on click', async () => {
82+
expect.assertions(11);
83+
// initially no branch were expanded nor rendered
9484
const wrapper = mount(G8TreeView, {propsData: tree});
9585
expect(wrapper.find('.g8-tree__node_expended').exists()).toBeFalsy();
96-
expect(wrapper.findAll('.g8-tree__branch').length).toBe(2);
97-
// click the first branch to expand it
86+
expect(wrapper.findAll('.g8-tree__branch').length).toBe(0);
87+
expect(wrapper.findAll('.g8-tree__node_label_text').length).toBe(1);
88+
// click the first branch to expand it and render the sub-tree
9889
wrapper.find('.g8-tree__node_label').trigger('click');
99-
await wrapper.vm.$nextTick();
100-
expect(wrapper.findAll('.g8-tree__node_expended').length).toBe(1);
101-
// click the second branch to expand it
90+
await wrapper.vm.$nextTick(() => {
91+
expect(wrapper.findAll('.g8-tree__node_expended').length).toBe(1);
92+
const labels = wrapper.findAll('.g8-tree__node_label_text');
93+
expect(labels.length).toBe(3);
94+
expect(labels.at(0).text()).toBe('root name');
95+
expect(labels.at(1).text()).toBe('item 1');
96+
});
97+
// click the second branch to expand it and render the sub-tree
10298
wrapper.findAll('.g8-tree__branch .g8-tree__node_label').trigger('click');
103-
await wrapper.vm.$nextTick();
104-
expect(wrapper.findAll('.g8-tree__node_expended').length).toBe(2);
99+
await wrapper.vm.$nextTick(() => {
100+
expect(wrapper.findAll('.g8-tree__node_expended').length).toBe(2);
101+
expect(wrapper.findAll('.g8-tree__node_label_text').length).toBe(5);
102+
});
105103
// click branches to collapse them all
106104
wrapper.findAll('.g8-tree__node_label').trigger('click');
107-
await wrapper.vm.$nextTick();
108-
expect(wrapper.find('.g8-tree__node_expended').exists()).toBeFalsy();
105+
await wrapper.vm.$nextTick(() => {
106+
expect(wrapper.find('.g8-tree__node_expended').exists()).toBeFalsy();
107+
expect(wrapper.findAll('.g8-tree__node_label_text').length).toBe(5);
108+
});
109109
});
110110

111111
it('emits click events', async () => {

0 commit comments

Comments
 (0)