Vue之使用JsonView来展示Json树

前两天干活儿有个需求,在前端需要展示可折叠的Json树,供开发人员查看,这里采用JsonView组件来实现,它是一款用于展示Json的Vue组件,支持大体积的Json文件快速解析渲染,下面记录一下实现过程。

1.首先先下载好JsonView的组件:JsonView.vue,组件代码如下:

  1 <template>
  2   <div class="bgView">
  3     <div :class="['json-view', length ? 'closeable' : '']" :style="'font-size:' + fontSize+'px'">
  4     <span @click="toggleClose" :class="['angle', innerclosed ? 'closed' : '']" v-if="length">
  5     </span>
  6       <div class="content-wrap">
  7         <p class="first-line">
  8           <span v-if="jsonKey" class="json-key">"{{jsonKey}}": </span>
  9           <span v-if="length">
 10           {{prefix}}
 11           {{innerclosed ? ('...' + subfix) : ''}}
 12           <span class="json-note">
 13            {{innerclosed ? (' // count: ' + length) : ''}}
 14           </span>
 15         </span>
 16           <span v-if="!length">{{isArray ? '[]' : '{}'}}</span>
 17         </p>
 18         <div v-if="!innerclosed && length" class="json-body">
 19           <template v-for="(item, index) in items">
 20             <json-view :closed="closed" v-if="item.isJSON" :key="index" :json="item.value"
 21                        :jsonKey="item.key" :isLast="index === items.length - 1"></json-view>
 22             <p class="json-item" v-else :key="index">
 23             <span class="json-key">
 24                 {{(isArray ? '' : '"' + item.key + '"')}}
 25             </span>
 26               :
 27               <span class="json-value">
 28                 {{item.value + (index === items.length - 1 ? '' : ',')}}
 29             </span>
 30             </p>
 31           </template>
 32           <span v-show="!innerclosed" class="body-line"></span>
 33         </div>
 34         <p v-if="!innerclosed && length" class="last-line">
 35           <span>{{subfix}}</span>
 36         </p>
 37       </div>
 38     </div>
 39   </div>
 40 </template>
 41 
 42 <script>
 43   export default {
 44     name: 'jsonView',
 45     props: {
 46       json: [Object, Array],
 47       jsonKey: {
 48         type: String,
 49         default: ''
 50       },
 51       closed: {
 52         type: Boolean,
 53         default: false
 54       },
 55       isLast: {
 56         type: Boolean,
 57         default: true
 58       },
 59       fontSize: {
 60         type: Number,
 61         default: 13
 62       }
 63     },
 64     created() {
 65       this.innerclosed = this.closed
 66       this.$watch('closed', () => {
 67         this.innerclosed = this.closed
 68       })
 69     },
 70     data() {
 71       return {
 72         innerclosed: true
 73       }
 74     },
 75     methods: {
 76       isObjectOrArray(source) {
 77         const type = Object.prototype.toString.call(source)
 78         const res = type === '[object Array]' || type === '[object Object]'
 79         return res
 80       },
 81       toggleClose() {
 82         if (this.innerclosed) {
 83           this.innerclosed = false
 84         } else {
 85           this.innerclosed = true
 86         }
 87       }
 88     },
 89     computed: {
 90       isArray() {
 91         return Object.prototype.toString.call(this.json) === '[object Array]'
 92       },
 93       length() {
 94         return this.isArray ? this.json.length : Object.keys(this.json).length
 95       },
 96       subfix() {
 97         return (this.isArray ? ']' : '}') + (this.isLast ? '' : ',')
 98       },
 99       prefix() {
100         return this.isArray ? '[' : '{'
101       },
102       items() {
103         if (this.isArray) {
104           return this.json.map(item => {
105             const isJSON = this.isObjectOrArray(item)
106             return {
107               value: isJSON ? item : JSON.stringify(item),
108               isJSON,
109               key: ''
110             }
111           })
112         }
113         const json = this.json
114         return Object.keys(json).map(key => {
115           const item = json[key]
116           const isJSON = this.isObjectOrArray(item)
117           return {
118             value: isJSON ? item : JSON.stringify(item),
119             isJSON,
120             key
121           }
122         })
123       }
124     }
125   }
126 </script>
127 
128 <style>
129   .bgView {
130     background-color: #fafafa;
131   }
132 
133   .json-view {
134     position: relative;
135     display: block;
136     width: 100%;
137     height: 100%;
138     white-space: nowrap;
139     padding-left: 20px;
140     box-sizing: border-box;
141   }
142 
143   .json-note {
144     color: #909399;
145   }
146 
147   .json-key {
148     color: rgb(147, 98, 15);
149   }
150 
151   .json-value {
152     color: rgb(24, 186, 24);
153   }
154 
155   .json-item {
156     margin: 0;
157     padding-left: 20px;
158   }
159 
160   .first-line {
161     padding: 0;
162     margin: 0;
163   }
164 
165   .json-body {
166     position: relative;
167     padding: 0;
168     margin: 0;
169   }
170 
171   .json-body .body-line {
172     position: absolute;
173     height: 100%;
174     width: 0;
175     border-left: dashed 1px #bbb;
176     top: 0;
177     left: 2px;
178   }
179 
180   .last-line {
181     padding: 0;
182     margin: 0;
183   }
184 
185   .angle {
186     position: absolute;
187     display: block;
188     cursor: pointer;
189     float: left;
190     width: 20px;
191     text-align: center;
192     left: 0;
193   }
194 
195   .angle::after {
196     content: "";
197     display: inline-block;
198     width: 0;
199     height: 0;
200     vertical-align: middle;
201     border-top: solid 4px #333;
202     border-left: solid 6px transparent;
203     border-right: solid 6px transparent;
204   }
205 
206   .angle.closed::after {
207     border-left: solid 4px #333;
208     border-top: solid 6px transparent;
209     border-bottom: solid 6px transparent;
210   }
211 </style>

2.在需要使用的vue页面中引用JsonView组件

import JsonView from '@/components/JsonView'

3.定义Json数据变量

jsonData:{},

4.页面展示代码

<JsonView :json="jsonData"></JsonView>

5.实现效果如下:

 

JsonView Attributes

 

打完收工!

 

posted @ 2019-12-20 10:10  慵懒的小景  阅读(7925)  评论(6编辑  收藏  举报
TOP 底部