2
0
mirror of https://github.com/tenrok/vue-json-viewer.git synced 2026-06-23 20:40:38 +03:00

rework of code extandable display + remove dependancy on ionicons + README & example

This commit is contained in:
STAFYNIAK Sacha
2018-09-18 00:13:39 +02:00
parent c29fa5680d
commit 65917b48a0
24 changed files with 6466 additions and 4069 deletions
+86 -31
View File
@@ -1,15 +1,14 @@
# vue-json-viewer # vue-json-viewer
Simple json display component, based on vue Simple JSON viewer component, for Vue.js 2
## Installing: ## Installing:
Using npm: Using npm:
``` ```
$ npm install vue-json-viewer $ npm install vue-json-viewer
``` ```
Using bower:
Using yarn:
``` ```
$ yarn add vue-json-viewer $ yarn add vue-json-viewer
``` ```
@@ -17,48 +16,104 @@ $ yarn add vue-json-viewer
## Example: ## Example:
``` html ``` html
<json-viewer :value="jsonData"></json-viewer>
<hr />
<json-viewer <json-viewer
:value="jsonData" :value="jsonData"
:show-copy="true" :expand-depth=5
icon-prefix="ion" copyable
:show-bigger="true" boxed
:sort-keys="true" /> sort></json-viewer>
``` ```
``` js ``` js
export default { import Vue from 'vue'
name: 'Page', import JsonViewer from '../lib'
// Import JsonViewer as a Vue.js plugin
Vue.use(JsonViewer)
new Vue({
el: '#app',
data() { data() {
return { return {
jsonData: { jsonData: {
name: [ total: 25,
{key: 2}, limit: 10,
{key: 'hello word'}, skip: 0,
], links: {
val: { previous: undefined,
c: () = {}, next: function () {},
b: 'a', },
a: 'hello word', data: [
asd2: 1, {
asd: false, id: '5968fcad629fa84ab65a5247',
foo: null, firstname: 'Ada',
bar: undefined lastname: 'Lovelace',
} awards: null,
known: [
'mathematics',
'computing'
],
position: {
lat: 44.563836,
lng: 6.495139
},
description: `Augusta Ada King, Countess of Lovelace (née Byron; 10 December 1815 27 November 1852) was an English mathematician and writer,
chiefly known for her work on Charles Babbage's proposed mechanical general-purpose computer,
the Analytical Engine. She was the first to recognise that the machine had applications beyond pure calculation,
and published the first algorithm intended to be carried out by such a machine.
As a result, she is sometimes regarded as the first to recognise the full potential of a "computing machine" and the first computer programmer.`,
bornAt: '1815-12-10T00:00:00.000Z',
diedAt: '1852-11-27T00:00:00.000Z'
}, {
id: '5968fcad629fa84ab65a5246',
firstname: 'Grace',
lastname: 'Hopper',
awards: [
'Defense Distinguished Service Medal',
'Legion of Merit',
'Meritorious Service Medal',
'American Campaign Medal',
'World War II Victory Medal',
'National Defense Service Medal',
'Armed Forces Reserve Medal',
'Naval Reserve Medal',
'Presidential Medal of Freedom'
],
known: null,
position: {
lat: 43.614624,
lng: 3.879995
},
description: `Grace Brewster Murray Hopper (née Murray; December 9, 1906 January 1, 1992)
was an American computer scientist and United States Navy rear admiral.
One of the first programmers of the Harvard Mark I computer,
she was a pioneer of computer programming who invented one of the first compiler related tools.
She popularized the idea of machine-independent programming languages, which led to the development of COBOL,
an early high-level programming language still in use today.`,
bornAt: '1815-12-10T00:00:00.000Z',
diedAt: '1852-11-27T00:00:00.000Z'
}
]
} }
} }
} }
} })
``` ```
## Result: ## Result:
![ABC](http://oxqqtdux0.bkt.clouddn.com/WX20180702-172158.png) ![preview](./example/preview.png)
## Options: ## Options:
| Property | Description | | Property | Description | Default |
| ----------- |:------------- | | ----------- |:------------- | ----------- |
| value | json data | | `value` | JSON data (can be used with `v-model`) | **Required** |
| show-copy | display the copy button | | `expand-depth` | Display the copy button | `1` |
| show-bigger | display the bigger button | | `copyable` | Display the copy button | `false` |
| icon-prefix | Custom Font icon prefix | | `sort` | Sort keys before displaying | `false` |
| sort-keys | Sort items by key names | | `boxed` | Add a fancy "boxed" style to component | `false` |
| `theme` | Add a custom CSS class for theming purposes | `jv-light` |
+69 -24
View File
@@ -1,27 +1,72 @@
import Vue from 'vue'; import Vue from 'vue'
import JsonViewer from '../lib'; import JsonViewer from '../lib'
import './css/ionicons.css';
Vue.use(JsonViewer)
new Vue({ new Vue({
el: '#app', el: '#app',
data() { data() {
return { return {
jsonData: { jsonData: {
name: [ total: 25,
{key: 2}, limit: 10,
{key: 'hello word'}, skip: 0,
], links: {
val: { previous: undefined,
c: function() {}, next: function () {},
b: 'a', },
a: 'hello word', data: [
asd2: 1, {
asd: false, id: '5968fcad629fa84ab65a5247',
foo: null, firstname: 'Ada',
bar: undefined lastname: 'Lovelace',
} awards: null,
} known: [
} 'mathematics',
}, 'computing'
components: {JsonViewer} ],
position: {
lat: 44.563836,
lng: 6.495139
},
description: `Augusta Ada King, Countess of Lovelace (née Byron; 10 December 1815 27 November 1852) was an English mathematician and writer,
chiefly known for her work on Charles Babbage's proposed mechanical general-purpose computer,
the Analytical Engine. She was the first to recognise that the machine had applications beyond pure calculation,
and published the first algorithm intended to be carried out by such a machine.
As a result, she is sometimes regarded as the first to recognise the full potential of a "computing machine" and the first computer programmer.`,
bornAt: '1815-12-10T00:00:00.000Z',
diedAt: '1852-11-27T00:00:00.000Z'
}, {
id: '5968fcad629fa84ab65a5246',
firstname: 'Grace',
lastname: 'Hopper',
awards: [
'Defense Distinguished Service Medal',
'Legion of Merit',
'Meritorious Service Medal',
'American Campaign Medal',
'World War II Victory Medal',
'National Defense Service Medal',
'Armed Forces Reserve Medal',
'Naval Reserve Medal',
'Presidential Medal of Freedom'
],
known: null,
position: {
lat: 43.614624,
lng: 3.879995
},
description: `Grace Brewster Murray Hopper (née Murray; December 9, 1906 January 1, 1992)
was an American computer scientist and United States Navy rear admiral.
One of the first programmers of the Harvard Mark I computer,
she was a pioneer of computer programming who invented one of the first compiler related tools.
She popularized the idea of machine-independent programming languages, which led to the development of COBOL,
an early high-level programming language still in use today.`,
bornAt: '1815-12-10T00:00:00.000Z',
diedAt: '1852-11-27T00:00:00.000Z'
}
]
}
}
}
}) })
File diff suppressed because one or more lines are too long
-11
View File
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.
Binary file not shown.
+16 -15
View File
@@ -1,22 +1,23 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>examples</title> <title>vue-json-viewer - example</title>
</head> </head>
<body> <body>
<div id="app"> <div id="app">
<json-viewer :value="jsonData"></json-viewer> <json-viewer :value="jsonData"></json-viewer>
<hr />
<json-viewer <hr />
:value="jsonData"
icon-prefix="ion" <json-viewer
boxed :value="jsonData"
sort :expand-depth=5
show-copy copyable
show-bigger></json-viewer> boxed
</div> sort></json-viewer>
</div>
</body> </body>
</html> </html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

+1 -1
View File
@@ -4,4 +4,4 @@ const install = Vue => {
Vue.component('JsonViewer', JsonView) Vue.component('JsonViewer', JsonView)
} }
export default Object.assign(JsonView, {install}) export default Object.assign(JsonView, { install })
+43 -36
View File
@@ -1,60 +1,78 @@
<template> <template>
<div class="jv-node"> <div class="jv-node">
<span class="jv-toggle" :class="{open: !!toggle}" v-if="keyName && isObject" @click.stop="toggleNode"></span> <span class="jv-toggle" :class="{open: !!expand}" v-if="keyName && isObject" @click.stop="toggleNode"></span>
<span class="jv-key" v-if="keyName"> <span class="jv-key" v-if="keyName">
{{keyName}}: {{keyName}}:
</span> </span>
<commponent v-model="toggle" <commponent
:expand.sync="expand"
:is="`Json${valueType}`" :is="`Json${valueType}`"
:json-value="value" :json-value="value"
:key-name="keyName" :key-name="keyName"
:sort="sort"></commponent> :sort="sort"
:depth="depth"></commponent>
</div> </div>
</template> </template>
<script> <script>
import JIcon from './json-icon' import JsonString from './types/json-string'
import JsonString from './types/json-string'; import JsonUndefined from './types/json-undefined'
import JsonUndefined from './types/json-undefined'; import JsonNumber from './types/json-number'
import JsonNumber from './types/json-number'; import JsonBoolean from './types/json-boolean'
import JsonBoolean from './types/json-boolean'; import JsonObject from './types/json-object'
import JsonObject from './types/json-object'; import JsonArray from './types/json-array'
import JsonArray from './types/json-array'; import JsonFunction from './types/json-function'
import JsonFunction from './types/json-function';
export default { export default {
name: 'JsonBox', name: 'JsonBox',
inject: ['expandDepth'],
props: { props: {
value: [Object, Array, String, Number, Boolean, Function], value: [Object, Array, String, Number, Boolean, Function],
keyName: String, keyName: String,
sort: Boolean sort: Boolean,
depth: {
type: Number,
default: 0
}
}, },
data() { data() {
return { return {
toggle: true expand: true
}; }
}, },
methods: { methods: {
toggleNode() { toggleNode() {
this.toggle = !this.toggle; this.expand = !this.expand
try {
this.$el.dispatchEvent(new Event("resized"))
} catch (e) {
// handle IE not supporting Event constructor
var evt = document.createEvent("Event")
evt.initEvent("resized", true, false)
this.$el.dispatchEvent(evt)
}
} }
}, },
mounted() {
this.expand = this.depth >= this.expandDepth ? false : true
},
computed: { computed: {
valueType() { valueType() {
if (this.value === null || this.value === undefined) { if (this.value === null || this.value === undefined) {
return 'Undefined'; return 'Undefined'
} else if (Array.isArray(this.value)) { } else if (Array.isArray(this.value)) {
return 'Array'; return 'Array'
} else if (typeof this.value === 'object') { } else if (typeof this.value === 'object') {
return 'Object'; return 'Object'
} else if (typeof this.value === 'number') { } else if (typeof this.value === 'number') {
return 'Number'; return 'Number'
} else if (typeof this.value === 'string') { } else if (typeof this.value === 'string') {
return 'String'; return 'String'
} else if (typeof this.value === 'boolean') { } else if (typeof this.value === 'boolean') {
return 'Boolean'; return 'Boolean'
} else if (typeof this.value === 'function') { } else if (typeof this.value === 'function') {
return 'Function'; return 'Function'
} }
}, },
isObject() { isObject() {
@@ -68,19 +86,14 @@ export default {
JsonObject, JsonObject,
JsonArray, JsonArray,
JsonFunction, JsonFunction,
JsonUndefined, JsonUndefined
JIcon
} }
}; }
</script> </script>
<style lang="scss"> <style lang="scss">
.jv-node { .jv-node {
font-size: 14px;
position: relative; position: relative;
color: #525252;
font-family: Consolas,Menlo,Courier,monospace;
white-space: nowrap;
&:after { &:after {
content: ',' content: ','
@@ -90,13 +103,7 @@ export default {
content: '' content: ''
} }
} }
/*.j-icon {
position: absolute;
left: -12px;
top: 3px;
color: #80848f;
cursor: pointer;
}*/
& .jv-node { & .jv-node {
margin-left: 25px; margin-left: 25px;
} }
-28
View File
@@ -1,28 +0,0 @@
<template>
<i class="j-icon" :class="{
[`${iconPrefix}`]: true,
[`${iconPrefix}-${type}`]: true
}" @click="iconClick"></i>
</template>
<script>
export default {
name: 'JsonIcon',
inject: ['iconPrefix'],
props: {
iconPrefix: {
type: String,
default: ''
},
type: {
type: String,
default: ''
}
},
methods: {
iconClick(e) {
this.$emit('click', e);
}
}
}
</script>
+134 -96
View File
@@ -1,37 +1,38 @@
<template> <template>
<div :class="jvClass"> <div :class="jvClass">
<div class="jv-tooltip" v-if="tooltip"> <div class="jv-tooltip" v-if="copyable">
<j-icon v-if="showBigger" type="qr-scanner" @click="bigger"></j-icon> <span class="jv-button" ref="clip" @click="clip" :class="{copied}">{{ copied ? 'copied!' : 'copy' }}</span>
<j-icon v-if="copied" class="copied" type="checkmark"></j-icon>
<j-icon v-if="showCopy && !copied" class="copy" type="clipboard" @click="clip"></j-icon>
</div> </div>
<div class="jv-code" :class="{'more': moreCode}"> <div class="jv-code" :class="{'open': expandCode}">
<json-box :value="value" :key-name="keyName" :sort="sort"></json-box> <json-box
ref="jsonBox"
:value="value"
:key-name="keyName"
:sort="sort"></json-box>
</div> </div>
<div class="jv-more" @click="toggleMoreCode"> <div v-if="expandableCode" class="jv-more" @click="toggleExpandCode">
<j-icon :type="moreCode ? 'ios-arrow-up' : 'ios-arrow-down'"></j-icon> <span class="jv-toggle" :class="{open: !!expandCode}"></span>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Vue from 'vue'; import Vue from 'vue'
import JIcon from './json-icon' import JsonBox from './json-box'
import JsonBox from './json-box'; import Clipboard from 'clipboard'
import Clipboard from 'clipboard';
Vue.component(JsonBox.name, JsonBox); Vue.component(JsonBox.name, JsonBox)
export default { export default {
name: 'JsonViewer', name: 'JsonViewer',
props: { props: {
value: [Object, Array, String, Number, Boolean], value: [Object, Array, String, Number, Boolean],
keyName: String, keyName: String,
showCopy: { expandDepth: {
type: Boolean, type: Number,
default: false default: 1
}, },
showBigger: { copyable: {
type: Boolean, type: Boolean,
default: false default: false
}, },
@@ -45,62 +46,68 @@ export default {
}, },
theme: { theme: {
type: String, type: String,
default: "jv-light" default: 'jv-light'
},
iconPrefix: {
type: String,
default: ''
}, },
}, },
provide() { provide() {
return { return {
iconPrefix: this.iconPrefix || 'ion' expandDepth: this.expandDepth,
} }
}, },
data() { data() {
return { return {
copied: false, copied: false,
biggerModal: false, expandableCode: false,
moreCode: false expandCode: false
}; }
},
mounted: function () {
this.onResized()
this.$el.addEventListener("resized", this.onResized, true)
}, },
computed: { computed: {
jvClass() { jvClass() {
return 'jv-container ' + this.theme + (this.boxed ? ' boxed' : '') return 'jv-container ' + this.theme + (this.boxed ? ' boxed' : '')
},
tooltip() {
return this.showBigger || this.copied || (this.showCopy && !this.copied)
} }
}, },
methods: { methods: {
clip() { onResized() {
const clipBoard = new Clipboard('.copy', { this.$nextTick(() => {
text: () => { if (this.$refs.jsonBox.$el.clientHeight >= 250) {
return JSON.stringify(this.value, null, 2); this.expandableCode = true
} else {
this.expandableCode = false
} }
}); })
},
clip() {
if (this.copied) {
return
}
const clipBoard = new Clipboard(this.$refs.clip, {
text: () => {
return JSON.stringify(this.value, null, 2)
}
})
clipBoard.on('success', () => { clipBoard.on('success', () => {
this.copied = true; this.copied = true
setTimeout(() => { setTimeout(() => {
this.copied = false; this.copied = false
}, 2000); }, 2000)
this.$emit('copied'); this.$emit('copied')
clipBoard.destroy(); clipBoard.destroy()
}); })
}, },
bigger() { toggleExpandCode() {
this.biggerModal = true; this.expandCode = !this.expandCode
},
toggleMoreCode() {
this.moreCode = !this.moreCode;
} }
}, },
components: { components: {
JsonBox, JsonBox
JIcon
} }
}; }
</script> </script>
<style lang="scss"> <style lang="scss">
@@ -121,6 +128,10 @@ export default {
&.jv-light { &.jv-light {
background: #fff; background: #fff;
white-space: nowrap;
color: #525252;
font-size: 14px;
font-family: Consolas, Menlo, Courier, monospace;
.jv-ellipsis { .jv-ellipsis {
color: #999; color: #999;
@@ -134,6 +145,7 @@ export default {
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
} }
.jv-button { color: #49b3ff }
.jv-key { color: #111111 } .jv-key { color: #111111 }
.jv-item { .jv-item {
&.jv-array { color: #111111 } &.jv-array { color: #111111 }
@@ -141,17 +153,23 @@ export default {
&.jv-function { color: #067bca } &.jv-function { color: #067bca }
&.jv-number { color: #fc1e70 } &.jv-number { color: #fc1e70 }
&.jv-object { color: #111111 } &.jv-object { color: #111111 }
&.jv-string { color: #42b983 }
&.jv-undefined { color: #e08331 } &.jv-undefined { color: #e08331 }
} &.jv-string {
.jv-toggle { color: #42b983;
&:before { word-break: break-word;
padding: 0px 2px; white-space: normal;
border-radius: 2px;
} }
&:hover { }
.jv-code {
.jv-toggle {
&:before { &:before {
background: #eee; padding: 0px 2px;
border-radius: 2px;
}
&:hover {
&:before {
background: #eee;
}
} }
} }
} }
@@ -162,49 +180,55 @@ export default {
overflow: hidden; overflow: hidden;
padding: 20px; padding: 20px;
.jv-toggle { &.open {
cursor: pointer;
&:before {
content: "⏶";
padding: 0px 2px;
border-radius: 2px;
position: absolute;
}
&:after {
content: " ";
position: relative;
display: inline-block;
width: 8px;
}
&.open {
&:before {
content: "⏷";
}
}
}
&.more {
max-height: initial; max-height: initial;
overflow: visible; overflow: visible;
overflow-x: auto; overflow-x: auto;
margin-bottom: 15px; padding-bottom: 45px;
}
}
.jv-toggle {
cursor: pointer;
&:before {
content: "⏷";
padding: 0px 2px;
border-radius: 2px;
position: absolute;
}
&:after {
content: " ";
position: relative;
display: inline-block;
width: 8px;
}
&.open {
&:before {
content: "⏶";
}
} }
} }
.jv-more { .jv-more {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
position: absolute; position: absolute;
z-index: 1;
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
height: 40px;
width: 100%;
text-align: center; text-align: center;
cursor: pointer; cursor: pointer;
.jv-toggle { .jv-toggle {
position: relative; position: relative;
top:40%;
z-index: 2; z-index: 2;
color: #888;
transition: all 0.1s;
// background: red;
} }
&:after { &:after {
@@ -215,25 +239,39 @@ export default {
bottom: 0; bottom: 0;
left: 0; left: 0;
z-index: 1; z-index: 1;
box-shadow: inset 0 -15px 30px #fff; background: linear-gradient(to bottom, rgba(0,0,0,0) 20%, rgba(230, 230, 230, 1) 100%);
transition: all 0.1s;
}
&:hover {
.jv-toggle {
top:50%;
color: #111;
}
&:after {
background: linear-gradient(to bottom, rgba(0,0,0,0) 20%, rgba(230, 230, 230, 0.3) 100%);
}
}
}
.jv-button {
position: relative;
cursor: pointer;
display: inline-block;
padding: 5px;
z-index: 5;
&.copied {
opacity: 0.4;
cursor: default;
} }
} }
.jv-tooltip { .jv-tooltip {
position: absolute; position: absolute;
right: 12px; right: 15px;
top: 5px; top: 10px;
color: #b2b2b2;
cursor: pointer;
.copied {
color: #19be6b;
}
.j-icon {
margin-left: 5px;
font-size: 18px;
}
} }
.j-icon { .j-icon {
+42 -16
View File
@@ -1,13 +1,23 @@
<template> <template>
<span> <span>
<span class="jv-toggle" :class="{open: !!value}" v-if="!keyName" @click.stop="toggle"></span> <span class="jv-toggle" :class="{open: !!expand}" v-if="!keyName" @click.stop="toggle"></span>
<span class="jv-item jv-array">[</span> <span class="jv-item jv-array">[</span>
<template v-if="jsonValue.length"> <template v-if="jsonValue.length">
<json-box v-show="value" v-for="(val, index) in jsonValue" :key="index" :value="val"></json-box> <json-box
<span v-show="!value" class="jv-ellipsis" @click.stop="toggle">...</span> v-show="expand"
</template> v-for="(val, index) in ordered"
<span class="jv-item jv-array"Z>]</span> :sort="sort"
</span> :key="index"
:value="val"
:depth="depth + 1"></json-box>
<span
v-show="!expand"
class="jv-ellipsis"
@click.stop="toggle"
:title="!expand ? `click to reveal ${jsonValue.length} hidden items` : ''">...</span>
</template>
<span class="jv-item jv-array"Z>]</span>
</span>
</template> </template>
<script> <script>
@@ -16,16 +26,32 @@ export default {
props: { props: {
jsonValue: Array, jsonValue: Array,
keyName: String, keyName: String,
value: Boolean sort: Boolean,
expand: Boolean,
depth: Number
},
computed: {
ordered () {
if (!this.sort) {
return this.jsonValue
}
return this.jsonValue.sort()
}
}, },
methods: { methods: {
toggle() { toggle() {
this.$emit('input', !this.value); this.$emit('update:expand', !this.expand)
try {
this.$el.dispatchEvent(new Event("resized"))
} catch (e) {
// handle IE not supporting Event constructor
var evt = document.createEvent("Event")
evt.initEvent("resized", true, false)
this.$el.dispatchEvent(evt)
}
} }
} }
}; }
</script> </script>
<style>
</style>
+6 -12
View File
@@ -1,18 +1,12 @@
<template> <template>
<span class="jv-item jv-boolean">{{jsonValue}}</span> <span class="jv-item jv-boolean">{{jsonValue}}</span>
</template> </template>
<script> <script>
export default { export default {
name: 'JsonBoolean', name: 'JsonBoolean',
props: { props: {
jsonValue: Boolean jsonValue: Boolean
} }
};
</script>
<style lang="scss">
.json-boolean {
color: #fc1e70;
} }
</style> </script>
+6 -12
View File
@@ -1,18 +1,12 @@
<template> <template>
<span class="jv-item jv-function">&lt;function&gt;</span> <span class="jv-item jv-function">&lt;function&gt;</span>
</template> </template>
<script> <script>
export default { export default {
name: 'JsonFunction', name: 'JsonFunction',
props: { props: {
jsonValue: Function jsonValue: Function
} }
};
</script>
<style lang="scss">
.json-function {
color: #067bca;
} }
</style> </script>
+6 -12
View File
@@ -1,18 +1,12 @@
<template> <template>
<span class="jv-item jv-number">{{jsonValue}}</span> <span class="jv-item jv-number">{{jsonValue}}</span>
</template> </template>
<script> <script>
export default { export default {
name: 'JsonNumber', name: 'JsonNumber',
props: { props: {
jsonValue: Number jsonValue: Number
} }
};
</script>
<style lang="scss">
.json-number {
color: #fc1e70;
} }
</style> </script>
+40 -27
View File
@@ -1,49 +1,62 @@
<template> <template>
<span> <span>
<span class="jv-toggle" :class="{open: !!value}" v-if="!keyName" @click.stop="toggle"></span> <span class="jv-toggle" :class="{open: !!expand}" v-if="!keyName" @click.stop="toggle"></span>
<span class="jv-item jv-object">{</span> <span class="jv-item jv-object">{</span>
<template v-if="Object.keys(ordered).length"> <template v-if="Object.keys(ordered).length">
<json-box v-show="value" v-for="(v, k) in ordered" :sort="sort" :key="k" :key-name="k" :value="v"></json-box> <json-box
<span v-show="!value" class="jv-ellipsis" @click.stop="toggle">...</span> v-show="expand"
</template> v-for="(v, k) in ordered"
<span class="jv-item jv-object">}</span> :sort="sort"
</span> :key="k"
:key-name="k"
:value="v"
:depth="depth + 1"></json-box>
<span
v-show="!expand"
class="jv-ellipsis"
@click.stop="toggle"
:title="!expand ? `click to reveal object content (keys: ${Object.keys(ordered).join(', ')})` : ''">...</span>
</template>
<span class="jv-item jv-object">}</span>
</span>
</template> </template>
<script> <script>
import JIcon from '../json-icon'
export default { export default {
name: 'JsonObject', name: 'JsonObject',
props: { props: {
jsonValue: Object, jsonValue: Object,
keyName: String, keyName: String,
value: Boolean, expand: Boolean,
sort: Boolean sort: Boolean,
depth: Number
}, },
computed: { computed: {
ordered () { ordered () {
if (!this.sortKeys) { if (!this.sort) {
return this.jsonValue; return this.jsonValue
} }
const ordered = {}; const ordered = {}
Object.keys(this.jsonValue).sort().forEach(key => { Object.keys(this.jsonValue).sort().forEach(key => {
ordered[key] = this.jsonValue[key]; ordered[key] = this.jsonValue[key]
}); })
return ordered; return ordered
} }
}, },
methods: { methods: {
toggle() { toggle() {
this.$emit('input', !this.value); this.$emit('update:expand', !this.expand)
try {
this.$el.dispatchEvent(new Event("resized"))
} catch (e) {
// handle IE not supporting Event constructor
var evt = document.createEvent("Event")
evt.initEvent("resized", true, false)
this.$el.dispatchEvent(evt)
}
} }
},
components: {
JIcon
} }
}; }
</script> </script>
<style>
</style>
+6 -12
View File
@@ -1,18 +1,12 @@
<template> <template>
<span class="jv-item jv-string">"{{jsonValue}}"</span> <span class="jv-item jv-string">"{{jsonValue}}"</span>
</template> </template>
<script> <script>
export default { export default {
name: 'JsonString', name: 'JsonString',
props: { props: {
jsonValue: String jsonValue: String
} }
};
</script>
<style lang="scss">
.json-string {
color: #42b983;
} }
</style> </script>
+6 -12
View File
@@ -1,18 +1,12 @@
<template> <template>
<span class="jv-item jv-undefined">{{ jsonValue === null ? 'null' : 'undefined' }}</span> <span class="jv-item jv-undefined">{{ jsonValue === null ? 'null' : 'undefined' }}</span>
</template> </template>
<script> <script>
export default { export default {
name: 'JsonUndefined', name: 'JsonUndefined',
props: { props: {
jsonValue: Object jsonValue: Object
} }
};
</script>
<style lang="scss">
.json-undefined {
color: #e08331;
} }
</style> </script>
+8 -8
View File
@@ -1,6 +1,6 @@
{ {
"name": "vue-json-viewer", "name": "vue-json-viewer",
"version": "1.0.4", "version": "2.0.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@@ -2030,12 +2030,12 @@
"dev": true "dev": true
}, },
"compressible": { "compressible": {
"version": "2.0.14", "version": "2.0.15",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.14.tgz", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz",
"integrity": "sha1-MmxfUH+7BV9UEWeCuWmoG2einac=", "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==",
"dev": true, "dev": true,
"requires": { "requires": {
"mime-db": ">= 1.34.0 < 2" "mime-db": ">= 1.36.0 < 2"
} }
}, },
"compression": { "compression": {
@@ -2887,9 +2887,9 @@
"dev": true "dev": true
}, },
"electron-to-chromium": { "electron-to-chromium": {
"version": "1.3.67", "version": "1.3.68",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.67.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.68.tgz",
"integrity": "sha512-h3zEBLdHvsKfaXv1SHAtykJyNtwYFEKkrWGSFyW1BzGgPQ4ykAzD5Hd8C5MZGTAEhkCKmtyIwYUrapsI0xfKww==", "integrity": "sha512-NHs9Xm6+ZUDkRj7t1tFwizzfMO2XZg0nmHNRRTurXHDUcEoz3Kdjs2mxXsd8drpEDfg5aVL0S8aypUCTA0HJ/Q==",
"dev": true "dev": true
}, },
"elliptic": { "elliptic": {
+6 -6
View File
@@ -1,8 +1,8 @@
{ {
"name": "vue-json-viewer", "name": "vue-json-viewer",
"version": "1.0.4", "version": "2.0.0",
"description": "vuejs展示json的组件", "description": "vuejs展示json的组件",
"main": "src/index.js", "main": "lib/index.js",
"files": [ "files": [
"lib/*" "lib/*"
], ],
@@ -33,12 +33,12 @@
}, },
"contributors": [ "contributors": [
{ {
"name": "陈峰", "name": "陈峰",
"email": "chenfengjw@hotmail.com" "email": "chenfengjw@hotmail.com"
}, },
{ {
"name": "Sacha Stafyniak", "name": "Sacha Stafyniak",
"email": "sacha.stafyniak@gmail.com" "email": "sacha.stafyniak@gmail.com"
} }
], ],
"dependencies": { "dependencies": {
+5991
View File
File diff suppressed because it is too large Load Diff