|
1 | 1 | <template>
|
2 | 2 | <div
|
3 |
| - class="vjs-tree" |
| 3 | + ref="tree" |
| 4 | + :class="{ |
| 5 | + 'vjs-tree': true, |
| 6 | + 'is-virtual': virtual |
| 7 | + }" |
| 8 | + @scroll="onTreeScroll" |
4 | 9 | >
|
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> |
26 | 34 | </div>
|
27 | 35 | </template>
|
28 | 36 |
|
|
52 | 60 | type: String,
|
53 | 61 | default: 'root'
|
54 | 62 | },
|
| 63 | + virtual: { |
| 64 | + type: Boolean, |
| 65 | + default: false |
| 66 | + }, |
| 67 | + itemHeight: { |
| 68 | + type: Number, |
| 69 | + default: 20 |
| 70 | + }, |
55 | 71 | // 是否显示数组|对象的长度
|
56 | 72 | showLength: {
|
57 | 73 | type: Boolean,
|
|
110 | 126 | },
|
111 | 127 | data () {
|
112 | 128 | return {
|
| 129 | + translateY: 0, |
| 130 | + visibleData: null, |
113 | 131 | hiddenPaths: jsonFlatten(this.data, this.path).reduce((acc, item) => {
|
114 | 132 | if ((item.type === 'objectStart' || item.type === 'arrayStart') && item.level === this.deep) {
|
115 | 133 | return {
|
|
147 | 165 |
|
148 | 166 | return startHiddenItem ? acc : acc.concat(item)
|
149 | 167 | }, [])
|
150 |
| - console.log(data); |
151 | 168 | return data
|
152 | 169 | },
|
153 | 170 |
|
|
176 | 193 | }
|
177 | 194 | },
|
178 | 195 | immediate: true
|
| 196 | + }, |
| 197 | +
|
| 198 | + flatData: { |
| 199 | + handler () { |
| 200 | + this.onTreeScroll() |
| 201 | + }, |
| 202 | + immediate: true |
179 | 203 | }
|
180 | 204 | },
|
181 | 205 | 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 | +
|
182 | 223 | onSelectedChange ({ path }) {
|
183 | 224 | const type = this.selectableType
|
184 | 225 | if (type === 'multiple') {
|
|
0 commit comments