Skip to content

Commit 2b0e974

Browse files
committed
feat: Support big data, use virtual list.(todo)
1 parent 3a912c2 commit 2b0e974

File tree

6 files changed

+80
-26
lines changed

6 files changed

+80
-26
lines changed

src/components/CheckController/styles.less

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
.@{css-prefix}-checkbox {
44
position: absolute;
5-
left: -@selectabl-span;
5+
left: 0;
66
color: #1f2d3d;
77
user-select: none;
88

@@ -62,7 +62,7 @@
6262

6363
.@{css-prefix}-radio {
6464
position: absolute;
65-
left: -@selectabl-span;
65+
left: 0;
6666
color: #1f2d3d;
6767
user-select: none;
6868

src/components/Tree/index.vue

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,36 @@
11
<template>
22
<div
3-
class="vjs-tree"
3+
ref="tree"
4+
:class="{
5+
'vjs-tree': true,
6+
'is-virtual': virtual
7+
}"
8+
@scroll="onTreeScroll"
49
>
5-
<tree-node
6-
v-for="(item) in flatData"
7-
:key="item.id"
8-
:node="item"
9-
:collapsed="!!hiddenPaths[item.path]"
10-
:custom-value-formatter="customValueFormatter"
11-
:show-double-quotes="showDoubleQuotes"
12-
:show-length="showLength"
13-
:collapsed-on-click-brackets="collapsedOnClickBrackets"
14-
:checked="selectedPaths.includes(item.path)"
15-
:selectable-type="selectableType"
16-
:show-line="showLine"
17-
:show-select-controller="showSelectController"
18-
:select-on-click-node="selectOnClickNode"
19-
:path-selectable="pathSelectable"
20-
:highlight-mouseover-node="highlightMouseoverNode"
21-
:highlight-selected-node="highlightSelectedNode"
22-
@tree-node-click="onTreeNodeClick"
23-
@brackets-click="onBracketsClick"
24-
@selected-change="onSelectedChange"
25-
/>
10+
<div :style="virtual && { height: `${flatData.length * itemHeight}px` }">
11+
<div :style="virtual && { transform: `translateY(${translateY}px)` }">
12+
<tree-node
13+
v-for="(item) in visibleData"
14+
:key="item.id"
15+
:node="item"
16+
:collapsed="!!hiddenPaths[item.path]"
17+
:custom-value-formatter="customValueFormatter"
18+
:show-double-quotes="showDoubleQuotes"
19+
:show-length="showLength"
20+
:collapsed-on-click-brackets="collapsedOnClickBrackets"
21+
:checked="selectedPaths.includes(item.path)"
22+
:selectable-type="selectableType"
23+
:show-line="showLine"
24+
:show-select-controller="showSelectController"
25+
:select-on-click-node="selectOnClickNode"
26+
:path-selectable="pathSelectable"
27+
:highlight-selected-node="highlightSelectedNode"
28+
@tree-node-click="onTreeNodeClick"
29+
@brackets-click="onBracketsClick"
30+
@selected-change="onSelectedChange"
31+
/>
32+
</div>
33+
</div>
2634
</div>
2735
</template>
2836

@@ -52,6 +60,14 @@
5260
type: String,
5361
default: 'root'
5462
},
63+
virtual: {
64+
type: Boolean,
65+
default: false
66+
},
67+
itemHeight: {
68+
type: Number,
69+
default: 20
70+
},
5571
// 是否显示数组|对象的长度
5672
showLength: {
5773
type: Boolean,
@@ -110,6 +126,8 @@
110126
},
111127
data () {
112128
return {
129+
translateY: 0,
130+
visibleData: null,
113131
hiddenPaths: jsonFlatten(this.data, this.path).reduce((acc, item) => {
114132
if ((item.type === 'objectStart' || item.type === 'arrayStart') && item.level === this.deep) {
115133
return {
@@ -147,7 +165,6 @@
147165
148166
return startHiddenItem ? acc : acc.concat(item)
149167
}, [])
150-
console.log(data);
151168
return data
152169
},
153170
@@ -176,9 +193,33 @@
176193
}
177194
},
178195
immediate: true
196+
},
197+
198+
flatData: {
199+
handler () {
200+
this.onTreeScroll()
201+
},
202+
immediate: true
179203
}
180204
},
181205
methods: {
206+
onTreeScroll() {
207+
if (this.virtual) {
208+
const visibleCount = 10;
209+
const scrollTop = this.$refs.tree && this.$refs.tree.scrollTop || 0
210+
const scrollCount = Math.floor(scrollTop / this.itemHeight)
211+
let start = scrollCount < 0 ? 0 : scrollCount + visibleCount > this.flatData.length ? this.flatData.length - visibleCount : scrollCount;
212+
if (start < 0) {
213+
start = 0
214+
}
215+
const end = start + visibleCount;
216+
this.translateY = start * this.itemHeight;
217+
this.visibleData = this.flatData.filter((item, index) => index >= start && index < end)
218+
} else {
219+
this.visibleData = this.flatData
220+
}
221+
},
222+
182223
onSelectedChange ({ path }) {
183224
const type = this.selectableType
184225
if (type === 'multiple') {

src/components/Tree/styles.less

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,12 @@
33
.@{css-prefix}-tree {
44
font-family: "Monaco", "Menlo", "Consolas", "Bitstream Vera Sans Mono", monospace;
55
font-size: 14px;
6+
7+
&.is-virtual {
8+
overflow: auto;
9+
10+
.@{css-prefix}-tree__node {
11+
white-space: nowrap;
12+
}
13+
}
614
}

src/components/TreeNode/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<div
33
:class="{
44
'vjs-tree__node': true,
5+
'has-selecter': showSelectController,
56
'is-highlight': highlightSelectedNode && checked
67
}"
78
@click="onTreeNodeClick"

src/components/TreeNode/styles.less

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
display: flex;
99
position: relative;
1010

11+
&.has-selecter {
12+
padding-left: @selecter-span;
13+
}
14+
1115
&.is-highlight,
1216
&:hover {
1317
background-color: @highlight-bg-color;

src/themes.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@
2323
@border-color: #bfcbd9;
2424

2525
/* 左侧可选区域占用空间 */
26-
@selectabl-span: 30px;
26+
@selecter-span: 30px;

0 commit comments

Comments
 (0)