组件代码(临时粘出来)
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"></span> 5 <div class="content-wrap"> 6 <p class="first-line"> 7 <span v-if="jsonKey" class="json-key">"{{jsonKey}}": </span> 8 <span v-if="length"> 9 {{prefix}} 10 {{innerclosed ? ('...' + subfix) : ''}} 11 <span class="json-note"> 12 {{innerclosed ? (' // count: ' + length) : ''}} 13 </span> 14 </span> 15 <span v-if="!length">{{isArray ? '[]' : '{}'}}</span> 16 </p> 17 <div v-if="!innerclosed && length" class="json-body"> 18 <template v-for="(item, index) in items"> 19 <json-view :closed="closed" v-if="item.isJSON" :key="index" :json="item.value" :jsonKey="item.key" 20 :isLast="index === items.length - 1"></json-view> 21 <p class="json-item" v-else :key="index"> 22 <span class="json-key"> 23 {{(isArray ? '' : '"' + item.key + '"')}} 24 </span> 25 : 26 <span class="json-value"> 27 {{item.value + (index === 28 items.length - 1 ? '' : ',')}} 29 </span> 30 31 </p> 32 </template> 33 <span v-show="!innerclosed" class="body-line"></span> 34 </div> 35 <p v-if="!innerclosed && length" class="last-line"> 36 <span>{{subfix}}</span> 37 </p> 38 </div> 39 </div> 40 </div> 41 </template> 42 43 <script> 44 export default { 45 name: 'jsonView', 46 props: { 47 json: [Object, Array], 48 jsonKey: { 49 type: String, 50 default: '' 51 }, 52 closed: { 53 type: Boolean, 54 default: false 55 }, 56 isLast: { 57 type: Boolean, 58 default: true 59 }, 60 fontSize: { 61 type: Number, 62 default: 18 63 } 64 }, 65 created() { 66 this.innerclosed = this.closed 67 this.$watch('closed', () => { 68 this.innerclosed = this.closed 69 }) 70 }, 71 data() { 72 return { 73 innerclosed: true 74 } 75 }, 76 methods: { 77 isObjectOrArray(source) { 78 const type = Object.prototype.toString.call(source) 79 const res = type === '[object Array]' || type === '[object Object]' 80 return res 81 }, 82 toggleClose() { 83 if (this.innerclosed) { 84 this.innerclosed = false 85 } else { 86 this.innerclosed = true 87 } 88 } 89 }, 90 computed: { 91 isArray() { 92 return Object.prototype.toString.call(this.json) === '[object Array]' 93 }, 94 length() { 95 return this.isArray ? this.json.length : Object.keys(this.json).length 96 }, 97 subfix() { 98 return (this.isArray ? ']' : '}') + (this.isLast ? '' : ',') 99 }, 100 prefix() { 101 return this.isArray ? '[' : '{' 102 }, 103 items() { 104 if (this.isArray) { 105 return this.json.map(item => { 106 const isJSON = this.isObjectOrArray(item) 107 return { 108 value: isJSON ? item : JSON.stringify(item), 109 isJSON, 110 key: '' 111 } 112 }) 113 } 114 const json = this.json 115 return Object.keys(json).map(key => { 116 const item = json[key] 117 const isJSON = this.isObjectOrArray(item) 118 return { 119 value: isJSON ? item : JSON.stringify(item), 120 isJSON, 121 key 122 } 123 }) 124 } 125 } 126 } 127 </script> 128 129 <style lang="scss"> 130 .bgView { 131 background-color: #fafafa; 132 } 133 .json-view { 134 position: relative; 135 display: block; 136 100%; 137 height: 100%; 138 white-space: nowrap; 139 padding-left: 20px; 140 box-sizing: border-box; 141 .json-note { 142 color: #909399; 143 } 144 .json-key { 145 color: rgb(147, 98, 15); 146 } 147 .json-value { 148 color: rgb(24, 186, 24); 149 } 150 .json-item { 151 margin: 0; 152 padding-left: 20px; 153 154 } 155 .first-line { 156 padding: 0; 157 margin: 0; 158 } 159 .json-body { 160 position: relative; 161 padding: 0; 162 margin: 0; 163 164 .body-line { 165 position: absolute; 166 height: 100%; 167 0; 168 border-left: dashed 1px #bbb; 169 top: 0; 170 left: 2px; 171 } 172 } 173 .last-line { 174 padding: 0; 175 margin: 0; 176 } 177 .angle { 178 position: absolute; 179 display: block; 180 cursor: pointer; 181 float: left; 182 20px; 183 text-align: center; 184 left: 0; 185 186 &::after { 187 content: ""; 188 display: inline-block; 189 0; 190 height: 0; 191 vertical-align: middle; 192 border-top: solid 4px #333; 193 border-left: solid 6px transparent; 194 border-right: solid 6px transparent; 195 } 196 &.closed::after { 197 border-left: solid 4px #333; 198 border-top: solid 6px transparent; 199 border-bottom: solid 6px transparent; 200 } 201 } 202 } 203 </style>
使用实例
<template> <div> <JsonView :json="JsonData"></JsonView> </div> </template> <script> import JsonView from '@/components/JsonView' export default { name: 'test', data() { return { JsonData: { 'code': 200, 'message': 'succeed !', 'data': [ { 'uuid': '76254DDB-A8EA-46CB-B3D7-6EEBD13BB2E6', 'version': 1, 'code': '401', 'message': '请求无权限', 'createId': 'dev', 'createDate': '2018-12-03T00:00:00', 'modifyId': null, 'modifyDate': null }, { 'uuid': 'B0415CC2-F0E0-4B0C-A3BA-50ABAEE98BB9', 'version': 1, 'code': '500', 'message': '服务器错误', 'createId': 'dev', 'createDate': '2018-12-03T00:00:00', 'modifyId': null, 'modifyDate': null }, { 'uuid': 'B70692E0-CCB7-4C44-B59B-7B75B16FA9FE', 'version': 1, 'code': '200', 'message': '请求成功', 'createId': 'dev', 'createDate': '2018-12-03T15:06:54.717', 'modifyId': null, 'modifyDate': null }, { 'uuid': 'C8A37C2D-0842-423B-AEBA-976C106A3E90', 'version': 1, 'code': '202', 'message': '请求失败', 'createId': 'dev', 'createDate': '2018-12-03T00:00:00', 'modifyId': null, 'modifyDate': null } ] } } }, components: { JsonView } } </script>
可传参数:
json: [Object, Array], // 必传 显示的数据 closed: { // 是否默认展开 type: Boolean, default: false }, fontSize: { // 文字大小 type: Number, default: 18 }