|
1 | 1 | <template>
|
2 | 2 | <div class="vjs__tree">
|
3 |
| - <span v-if="!child && show" class="vjs__tree__node" @click="toggle">{{ isArray(json) ? '[' : '{' }}</span> |
4 |
| - <span v-show="!show" class="vjs__tree__node" @click.stop="toggle"> |
5 |
| - {{ isArray(json) ? '[...]' : '{...}' }} |
6 |
| - </span> |
| 3 | + <brackets-left |
| 4 | + :visiable.sync="visiable" |
| 5 | + :data="data" |
| 6 | + :index="index" |
| 7 | + :last-index="lastIndex"> |
| 8 | + <span v-if="child && Array.isArray(data)">{{ index }}:</span> |
| 9 | + </brackets-left> |
7 | 10 |
|
| 11 | + <!-- data 为对象时, index 表示 key, 为数组才表示索引 --> |
8 | 12 | <div
|
9 |
| - v-for="(item, index) in json" |
10 |
| - v-show="show" |
| 13 | + v-for="(item, index) in data" |
| 14 | + v-show="visiable" |
11 | 15 | class="vjs__tree__content"
|
12 | 16 | :style="{ 'background-color': treeContentBackground }"
|
13 | 17 | :key="index"
|
14 | 18 | @mouseover.stop="treeContentBackground = '#eee'"
|
15 | 19 | @mouseout.stop="treeContentBackground = 'transparent'"
|
16 |
| - @click.stop="getItemData"> |
17 |
| - <tree-child |
18 |
| - v-if="isArray(item) || isObject(item)" |
| 20 | + @click.stop="handleClick"> |
| 21 | + <tree |
| 22 | + v-if="Array.isArray(item) || isObject(item)" |
| 23 | + :data="item" |
| 24 | + :path="path + (Array.isArray(data) ? `[${index}]` : `.${index}`)" |
19 | 25 | :index="index"
|
20 |
| - :data="json" |
21 |
| - :item="item"> |
22 |
| - <tree |
23 |
| - :data="item" |
24 |
| - :child="true" |
25 |
| - :path="path + (isArray(json) ? `[${index}]` : `.${index}`)"> |
26 |
| - </tree> |
27 |
| - </tree-child> |
| 26 | + :last-index="getLastIndex()" |
| 27 | + :child="true" |
| 28 | + @click="handleItemClick"> |
| 29 | + </tree> |
28 | 30 |
|
29 |
| - <div v-else :class="{ 'vjs__lastIndex': index !== lastIndex }" > |
30 |
| - <span v-if="isObject(json)">{{ index }}:</span> |
| 31 | + <div v-else :class="{ 'vjs__not__lastIndex': index !== getLastIndex() }" > |
| 32 | + <span v-if="isObject(data)">{{ index }}:</span> |
31 | 33 | <span :class="getValueClass(item)">{{ `${item}` }}</span>
|
32 | 34 | </div>
|
33 | 35 | </div>
|
34 | 36 |
|
35 |
| - <span v-if="!child && show" class="vjs__tree__node" @click.stop="toggle"> |
36 |
| - {{ isArray(json) ? ']' : '}' }} |
37 |
| - </span> |
| 37 | + <brackets-right |
| 38 | + :visiable.sync="visiable" |
| 39 | + :data="data" |
| 40 | + :index="index" |
| 41 | + :last-index="lastIndex"> |
| 42 | + </brackets-right> |
38 | 43 | </div>
|
39 | 44 | </template>
|
40 | 45 |
|
41 | 46 | <script>
|
42 |
| - import TreeChild from './tree-child' |
43 |
| - import mixin from 'src/mixins/mixin' |
| 47 | + import BracketsLeft from './brackets-left' |
| 48 | + import BracketsRight from './brackets-right' |
44 | 49 |
|
45 | 50 | export default {
|
46 | 51 | name: 'tree',
|
47 |
| - mixins: [mixin], |
48 | 52 | props: {
|
49 | 53 | data: {},
|
50 | 54 | child: Boolean,
|
51 | 55 | path: {
|
52 | 56 | type: String,
|
53 |
| - default: 'res' |
54 |
| - } |
| 57 | + default: 'root' |
| 58 | + }, |
| 59 | + index: {}, |
| 60 | + lastIndex: {} |
55 | 61 | },
|
56 | 62 | data () {
|
57 | 63 | return {
|
| 64 | + visiable: true, |
58 | 65 | treeContentBackground: 'transparent'
|
59 | 66 | }
|
60 | 67 | },
|
61 | 68 | components: {
|
62 |
| - TreeChild |
63 |
| - }, |
64 |
| - computed: { |
65 |
| - json () { |
66 |
| - return JSON.parse(JSON.stringify(this.data)) |
67 |
| - } |
| 69 | + BracketsLeft, |
| 70 | + BracketsRight |
68 | 71 | },
|
69 | 72 | methods: {
|
70 |
| - getItemData () { |
71 |
| - console.log('path: ', this.path) |
72 |
| - console.log('data: ', this.json) |
| 73 | + // 触发组件的 click 事件 |
| 74 | + handleClick () { |
| 75 | + this.$emit('click', this.path, this.data) |
| 76 | + }, |
| 77 | + // 处理子树触发的 click 事件, 并传递到顶层 |
| 78 | + handleItemClick (path, data) { |
| 79 | + this.$emit('click', path, data) |
| 80 | + }, |
| 81 | + // 工具函数: 判断是否对象 |
| 82 | + isObject (value) { |
| 83 | + return Object.prototype.toString.call(value).slice(8, -1).toLowerCase() === 'object' |
| 84 | + }, |
| 85 | + // 获取当前 data 中最后一项的 key 或 索引, 便于界面判断是否添加 "," |
| 86 | + getLastIndex () { |
| 87 | + if (Array.isArray(this.data)) { |
| 88 | + return this.data.length - 1 |
| 89 | + } else if (this.isObject(this.data)) { |
| 90 | + let arr = Object.keys(this.data) |
| 91 | + return arr[arr.length - 1] |
| 92 | + } |
73 | 93 | },
|
74 | 94 | getValueClass (value) {
|
75 | 95 | if (value === null) {
|
|
97 | 117 | color: #20a0ff;
|
98 | 118 | }
|
99 | 119 | }
|
100 |
| - .vjs__lastIndex:after { |
| 120 | + .vjs__not__lastIndex:after { |
101 | 121 | content: ",";
|
102 | 122 | }
|
103 | 123 | .vjs__value__null {
|
|
0 commit comments