mirror of
https://github.com/tenrok/vue-json-viewer.git
synced 2026-06-20 20:00:37 +03:00
Merge pull request #84 from mlanin-forks/feature/expand-all
Add ability to expand full branch
This commit is contained in:
@@ -147,3 +147,8 @@ nbproject/*
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.devhost
|
.devhost
|
||||||
examples/dist/
|
examples/dist/
|
||||||
|
/vue-json-viewer.js
|
||||||
|
/ssr.js
|
||||||
|
/style.css
|
||||||
|
yarn.lock
|
||||||
|
package-lock.json
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
language : node_js
|
|
||||||
node_js:
|
|
||||||
- "10"
|
|
||||||
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
|
|
||||||
install:
|
|
||||||
- npm install
|
|
||||||
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- name: deploy
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
include:
|
|
||||||
- stage: deploy
|
|
||||||
script:
|
|
||||||
- echo "NPM Deploying Started ..."
|
|
||||||
- npm version
|
|
||||||
- npm run build
|
|
||||||
- echo "NPM Building Finished."
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
provider: npm
|
|
||||||
email: chenfengjw@hotmail.com
|
|
||||||
api_key: "$NPM_TOKEN"
|
|
||||||
skip_cleanup: true
|
|
||||||
on:
|
|
||||||
all_branches: true
|
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
## 2.2.20 2021-10-31
|
||||||
|
|
||||||
|
- 给box加getPath方法 [pr](https://github.com/chenfengjw163/vue-json-viewer/pull/79)
|
||||||
|
- chore: move "vue" to "peerDependencies" [pr](https://github.com/chenfengjw163/vue-json-viewer/pull/75)
|
||||||
|
|
||||||
|
|
||||||
|
## 2.2.17 2020-12-29
|
||||||
|
|
||||||
|
- fix: issues [issues](https://github.com/chenfengjw163/vue-json-viewer/issues/64)
|
||||||
|
- fix: issues [issues](https://github.com/chenfengjw163/vue-json-viewer/issues/65)
|
||||||
|
- fix: issues [issues](https://github.com/chenfengjw163/vue-json-viewer/issues/66)
|
||||||
|
|
||||||
|
## 2.2.17 2020-12-29
|
||||||
|
|
||||||
|
- fix: long string expand arrow display error [pr](https://github.com/chenfengjw163/vue-json-viewer/pull/62)
|
||||||
|
|
||||||
|
## 2.2.16 2020-11-13
|
||||||
|
|
||||||
|
- support long string expand [issues](https://github.com/chenfengjw163/vue-json-viewer/issues/60)
|
||||||
|
|
||||||
|
## 2.2.15 2020-10-13
|
||||||
|
|
||||||
|
- Add Preview Mode
|
||||||
|
|
||||||
|
## 2.2.14 2020-07-27
|
||||||
|
|
||||||
|
- Allow add specific style for float and integer numbers [pr](https://github.com/chenfengjw163/vue-json-viewer/pull/51)
|
||||||
|
|
||||||
|
|
||||||
|
## 2.2.13 2020-07-14
|
||||||
|
|
||||||
|
- Add timeformat props to support custom time format [pr](https://github.com/chenfengjw163/vue-json-viewer/pull/48)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 陈峰
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -1,24 +1,37 @@
|
|||||||
# vue-json-viewer
|
# vue-json-viewer
|
||||||
|
|
||||||
Simple JSON viewer component, for Vue.js 2
|
[中文版](https://github.com/chenfengjw163/vue-json-viewer/blob/master/README_CN.md)
|
||||||
|
|
||||||
[](https://travis-ci.org/<chenfengjw163>/<vue-json-viewer>)
|
Simple JSON viewer component, for Vue.js 2 or 3.
|
||||||
|
|
||||||
|
Support for incremental update components
|
||||||
|
|
||||||
|
[](https://travis-ci.org/chenfengjw163/vue-json-viewer)
|
||||||
|
[](https://www.npmjs.com/package/vue-json-viewer)
|
||||||
|

|
||||||
|
|
||||||
- [Installing](#installing)
|
- [Installing](#installing)
|
||||||
- [Example](#example)
|
- [Example](#example)
|
||||||
- [Options](#options)
|
- [Options](#options)
|
||||||
|
- [Listeners](#listeners)
|
||||||
|
- [Slots](#slots)
|
||||||
- [Theming](#theming)
|
- [Theming](#theming)
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
Using npm:
|
Using npm:
|
||||||
```
|
```
|
||||||
$ npm install vue-json-viewer --save
|
$ npm install vue-json-viewer@2 --save
|
||||||
|
// Vue2
|
||||||
|
$ npm install vue-json-viewer@3 --save
|
||||||
|
// Vue3
|
||||||
```
|
```
|
||||||
|
|
||||||
Using yarn:
|
Using yarn:
|
||||||
```
|
```
|
||||||
$ yarn add vue-json-viewer
|
$ yarn add vue-json-viewer@2
|
||||||
|
// Vue2
|
||||||
|
$ yarn add vue-json-viewer@3
|
||||||
|
// Vue3
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
@@ -38,10 +51,13 @@ $ yarn add vue-json-viewer
|
|||||||
|
|
||||||
``` js
|
``` js
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import JsonViewer from '../lib'
|
import JsonViewer from 'vue-json-viewer'
|
||||||
|
|
||||||
// Import JsonViewer as a Vue.js plugin
|
// Import JsonViewer as a Vue.js plugin
|
||||||
Vue.use(JsonViewer)
|
Vue.use(JsonViewer)
|
||||||
|
// or
|
||||||
|
// components: {JsonViewer}
|
||||||
|
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
@@ -111,6 +127,22 @@ new Vue({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
### SSR
|
||||||
|
``` js
|
||||||
|
import JsonViewer from 'vue-json-viewer/ssr'
|
||||||
|
|
||||||
|
// Import JsonViewer as a Vue.js plugin
|
||||||
|
Vue.use(JsonViewer)
|
||||||
|
// or
|
||||||
|
// components: {JsonViewer}
|
||||||
|
```
|
||||||
|
and
|
||||||
|
|
||||||
|
``` js
|
||||||
|
import 'vue-json-viewer/style.css'
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Preview
|
### Preview
|
||||||

|

|
||||||
|
|
||||||
@@ -121,10 +153,25 @@ new Vue({
|
|||||||
| ----------- |:------------- | ----------- |
|
| ----------- |:------------- | ----------- |
|
||||||
| `value` | JSON data (can be used with `v-model`) | **Required** |
|
| `value` | JSON data (can be used with `v-model`) | **Required** |
|
||||||
| `expand-depth` | Collapse blocs under this depth | `1` |
|
| `expand-depth` | Collapse blocs under this depth | `1` |
|
||||||
| `copyable` | Display the copy button | `false` |
|
| `copyable` | Display the copy button, you can customize copy text just set `{copyText: 'copy', copiedText: 'copied', timeout: 2000}` or set `true` use default copytext | `false` |
|
||||||
| `sort` | Sort keys before displaying | `false` |
|
| `sort` | Sort keys before displaying | `false` |
|
||||||
| `boxed` | Add a fancy "boxed" style to component | `false` |
|
| `boxed` | Add a fancy "boxed" style to component | `false` |
|
||||||
| `theme` | Add a custom CSS class for theming purposes | `jv-light` |
|
| `theme` | Add a custom CSS class for theming purposes | `jv-light` |
|
||||||
|
| `expanded` | Default expand the view | `false` |
|
||||||
|
| `timeformat` | custom time format function | time => time.toLocaleString() |
|
||||||
|
| `preview-mode` | no expand mode | `false` |
|
||||||
|
|
||||||
|
## Listeners
|
||||||
|
|
||||||
|
| Listener | Description | Value |
|
||||||
|
| ----------- |:------------- | ----------- |
|
||||||
|
| `copied` | Emits copyEvent after text copied | Clipboard success event |
|
||||||
|
|
||||||
|
## Slots
|
||||||
|
|
||||||
|
| Name | Description | Scope |
|
||||||
|
| ----------- |:------------- | ----------- |
|
||||||
|
| `copy` | Custom content for copy button | `{copied: boolean}` |
|
||||||
|
|
||||||
## Theming
|
## Theming
|
||||||
|
|
||||||
@@ -160,6 +207,8 @@ To create custom theme, (e.g. `my-awesome-json-theme`), in two easy steps:
|
|||||||
&.jv-boolean { color: #fc1e70 }
|
&.jv-boolean { color: #fc1e70 }
|
||||||
&.jv-function { color: #067bca }
|
&.jv-function { color: #067bca }
|
||||||
&.jv-number { color: #fc1e70 }
|
&.jv-number { color: #fc1e70 }
|
||||||
|
&.jv-number-float { color: #fc1e70 }
|
||||||
|
&.jv-number-integer { color: #fc1e70 }
|
||||||
&.jv-object { color: #111111 }
|
&.jv-object { color: #111111 }
|
||||||
&.jv-undefined { color: #e08331 }
|
&.jv-undefined { color: #e08331 }
|
||||||
&.jv-string {
|
&.jv-string {
|
||||||
|
|||||||
+216
@@ -0,0 +1,216 @@
|
|||||||
|
# vue-json-viewer
|
||||||
|
|
||||||
|
简单易用的json内容展示组件,支持vue@2和3,支持SSR,组件支持增量渲染即使大文件json也可以快速渲染。
|
||||||
|
|
||||||
|
[](https://travis-ci.org/chenfengjw163/vue-json-viewer)
|
||||||
|
[](https://www.npmjs.com/package/vue-json-viewer)
|
||||||
|

|
||||||
|
|
||||||
|
- [安装](#安装)
|
||||||
|
- [示例](#示例)
|
||||||
|
- [选项](#选项)
|
||||||
|
- [主题](#主题)
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
使用 npm:
|
||||||
|
```
|
||||||
|
$ npm install vue-json-viewer@2 --save
|
||||||
|
// Vue2
|
||||||
|
$ npm install vue-json-viewer@3 --save
|
||||||
|
// Vue3
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 yarn:
|
||||||
|
```
|
||||||
|
$ yarn add vue-json-viewer@2
|
||||||
|
// Vue2
|
||||||
|
$ yarn add vue-json-viewer@3
|
||||||
|
// Vue3
|
||||||
|
```
|
||||||
|
|
||||||
|
## 示例
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<json-viewer :value="jsonData"></json-viewer>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<json-viewer
|
||||||
|
:value="jsonData"
|
||||||
|
:expand-depth=5
|
||||||
|
copyable
|
||||||
|
boxed
|
||||||
|
sort></json-viewer>
|
||||||
|
```
|
||||||
|
|
||||||
|
``` js
|
||||||
|
import Vue from 'vue'
|
||||||
|
import JsonViewer from 'vue-json-viewer'
|
||||||
|
|
||||||
|
// Import JsonViewer as a Vue.js plugin
|
||||||
|
Vue.use(JsonViewer)
|
||||||
|
// or
|
||||||
|
// components: {JsonViewer}
|
||||||
|
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
jsonData: {
|
||||||
|
total: 25,
|
||||||
|
limit: 10,
|
||||||
|
skip: 0,
|
||||||
|
links: {
|
||||||
|
previous: undefined,
|
||||||
|
next: function () {},
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: '5968fcad629fa84ab65a5247',
|
||||||
|
firstname: 'Ada',
|
||||||
|
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'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
### 支持SSR
|
||||||
|
``` js
|
||||||
|
import JsonViewer from 'vue-json-viewer/ssr'
|
||||||
|
|
||||||
|
// Import JsonViewer as a Vue.js plugin
|
||||||
|
Vue.use(JsonViewer)
|
||||||
|
// or
|
||||||
|
// components: {JsonViewer}
|
||||||
|
```
|
||||||
|
and
|
||||||
|
|
||||||
|
``` js
|
||||||
|
import 'vue-json-viewer/style.css'
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 图片预览
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## 选项
|
||||||
|
|
||||||
|
| 属性 | 描述 | 默认值 |
|
||||||
|
| ----------- |:------------- | ----------- |
|
||||||
|
| `value` | json对象的值,可以使用v-model,支持响应式 | **必填** |
|
||||||
|
| `expand-depth` | 默认展开的层级 | `1` |
|
||||||
|
| `copyable` | 展示复制按钮,默认文案为:copy、copied!, 你可以设置一个对象`{copyText: 'copy', copiedText: 'copied'}` 来自定义复制按钮文案 | `false` |
|
||||||
|
| `sort` | 按照key排序展示 | `false` |
|
||||||
|
| `boxed` | 为组件添加一个盒样式 | `false` |
|
||||||
|
| `theme` | 添加一个自定义的样式class用作主题 | `jv-light` |
|
||||||
|
| `expanded` | 默认展开视图 | `false` |
|
||||||
|
| `timeformat` | 自定义时间格式函数 | time => time.toLocaleString() |
|
||||||
|
| `preview-mode` | 不可折叠模式,默认全部展开 | `false` |
|
||||||
|
|
||||||
|
## 主题
|
||||||
|
|
||||||
|
有两个办法创建自定义主题, (e.g. `my-awesome-json-theme`):
|
||||||
|
1. 添加 `theme="my-awesome-json-theme"` JsonViewer的组件属性
|
||||||
|
2. 复制粘贴下面的模板并且根据自定义的theme名称做对应调整:
|
||||||
|
|
||||||
|
``` scss
|
||||||
|
// values are default one from jv-light template
|
||||||
|
.my-awesome-json-theme {
|
||||||
|
background: #fff;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: #525252;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: Consolas, Menlo, Courier, monospace;
|
||||||
|
|
||||||
|
.jv-ellipsis {
|
||||||
|
color: #999;
|
||||||
|
background-color: #eee;
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 0.9;
|
||||||
|
font-size: 0.9em;
|
||||||
|
padding: 0px 4px 2px 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
vertical-align: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.jv-button { color: #49b3ff }
|
||||||
|
.jv-key { color: #111111 }
|
||||||
|
.jv-item {
|
||||||
|
&.jv-array { color: #111111 }
|
||||||
|
&.jv-boolean { color: #fc1e70 }
|
||||||
|
&.jv-function { color: #067bca }
|
||||||
|
&.jv-number { color: #fc1e70 }
|
||||||
|
&.jv-number-float { color: #fc1e70 }
|
||||||
|
&.jv-number-integer { color: #fc1e70 }
|
||||||
|
&.jv-object { color: #111111 }
|
||||||
|
&.jv-undefined { color: #e08331 }
|
||||||
|
&.jv-string {
|
||||||
|
color: #42b983;
|
||||||
|
word-break: break-word;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.jv-code {
|
||||||
|
.jv-toggle {
|
||||||
|
&:before {
|
||||||
|
padding: 0px 2px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
&:before {
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
+27
-16
@@ -1,14 +1,29 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const webpack = require('webpack')
|
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||||
|
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
mode: 'production',
|
||||||
entry: './lib/index.js',
|
entry: './lib/index.js',
|
||||||
|
optimization: {
|
||||||
|
minimizer: [
|
||||||
|
new UglifyJsPlugin({
|
||||||
|
cache: true,
|
||||||
|
parallel: true,
|
||||||
|
sourceMap: true,
|
||||||
|
uglifyOptions: {
|
||||||
|
comments: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, '../dist'),
|
path: path.join(__dirname, '../'),
|
||||||
filename: 'vue-json-viewer.js',
|
filename: 'vue-json-viewer.js',
|
||||||
libraryTarget: 'umd',
|
libraryTarget: 'umd',
|
||||||
library: 'JsonView'
|
library: 'JsonView',
|
||||||
|
globalObject: 'this'
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.js', '.vue'],
|
extensions: ['.js', '.vue'],
|
||||||
@@ -17,7 +32,8 @@ module.exports = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
externals: {
|
externals: {
|
||||||
vue: 'vue'
|
vue: 'vue',
|
||||||
|
clipboard: 'clipboard'
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
@@ -27,8 +43,8 @@ module.exports = {
|
|||||||
exclude: /node_modules/
|
exclude: /node_modules/
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.s?css$/,
|
||||||
use: ['vue-style-loader', 'css-loader', 'autoprefixer-loader']
|
use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||||
@@ -55,15 +71,10 @@ module.exports = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new webpack.optimize.UglifyJsPlugin({
|
new VueLoaderPlugin()
|
||||||
parallel: true,
|
|
||||||
uglifyOptions: {
|
|
||||||
compress: {
|
|
||||||
warnings: false
|
|
||||||
},
|
|
||||||
comments: false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
// new BundleAnalyzerPlugin()
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (process.argv.some(a => a === '--report')) {
|
||||||
|
module.exports.plugins.push(new BundleAnalyzerPlugin());
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||||
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
|
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||||
|
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||||
|
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: 'production',
|
||||||
|
entry: './lib/index.js',
|
||||||
|
optimization: {
|
||||||
|
minimizer: [
|
||||||
|
new UglifyJsPlugin({
|
||||||
|
cache: true,
|
||||||
|
parallel: true,
|
||||||
|
sourceMap: false,
|
||||||
|
uglifyOptions: {
|
||||||
|
comments: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new OptimizeCSSAssetsPlugin({
|
||||||
|
cssProcessorOptions: { safe: true, sourceMap: false}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
path: path.join(__dirname, '../'),
|
||||||
|
filename: 'ssr.js',
|
||||||
|
libraryTarget: 'umd',
|
||||||
|
library: 'JsonView',
|
||||||
|
globalObject: 'this'
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.js', '.vue'],
|
||||||
|
modules: [
|
||||||
|
'node_modules'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
externals: {
|
||||||
|
vue: 'vue',
|
||||||
|
clipboard: 'clipboard'
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
loader: 'babel-loader',
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.s?css$/,
|
||||||
|
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||||
|
loader: 'url-loader',
|
||||||
|
options: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'img/[name].[ext]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||||
|
loader: 'url-loader',
|
||||||
|
options: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'fonts/[name].[ext]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.vue$/,
|
||||||
|
use: [{
|
||||||
|
loader: 'vue-loader'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new VueLoaderPlugin(),
|
||||||
|
new MiniCssExtractPlugin({
|
||||||
|
filename: 'style.css',
|
||||||
|
allChunks: true,
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.argv.some(a => a === '--report')) {
|
||||||
|
module.exports.plugins.push(new BundleAnalyzerPlugin());
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
.jv-number-float {
|
||||||
|
color: #faa !important;
|
||||||
|
}
|
||||||
|
.jv-key-node {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
+44
-6
@@ -1,21 +1,57 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import JsonViewer from '../dist/vue-json-viewer'
|
import JsonViewer from '../lib'
|
||||||
|
import './app.css'
|
||||||
|
|
||||||
Vue.use(JsonViewer)
|
Vue.use(JsonViewer)
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
render() {
|
render() {
|
||||||
|
const scopedSlots = {
|
||||||
|
copy: ({ copied }) => {
|
||||||
|
if (copied) return <button disabled>Copied!</button>
|
||||||
|
return <button>Copy me!</button>
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const onCopied = (copyEvent) => {
|
||||||
|
alert(`Text successfully copied!\n${copyEvent.text}`);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<json-viewer
|
||||||
|
preview-mode
|
||||||
|
value={{
|
||||||
|
data: {
|
||||||
|
data: {
|
||||||
|
data: {
|
||||||
|
a: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}></json-viewer>
|
||||||
<json-viewer value={this.jsonData}></json-viewer>
|
<json-viewer value={this.jsonData}></json-viewer>
|
||||||
<hr />
|
<hr />
|
||||||
<json-viewer
|
<json-viewer
|
||||||
value={this.jsonData}
|
value={this.jsonData}
|
||||||
expand-depth={5}
|
expand-depth={5}
|
||||||
copyable
|
copyable={{
|
||||||
|
copyText: '复制',
|
||||||
|
copiedText: '复制成功',
|
||||||
|
align: 'left'
|
||||||
|
}}
|
||||||
boxed
|
boxed
|
||||||
|
timeformat={time => new Date(time)}
|
||||||
sort></json-viewer>
|
sort></json-viewer>
|
||||||
|
<hr />
|
||||||
|
<json-viewer
|
||||||
|
value={this.jsonData}
|
||||||
|
expand-depth={1}
|
||||||
|
copyable={{
|
||||||
|
timeout: 4000,
|
||||||
|
align: 'left'
|
||||||
|
}}
|
||||||
|
scopedSlots={scopedSlots}
|
||||||
|
onCopied={onCopied}></json-viewer>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@@ -25,6 +61,7 @@ new Vue({
|
|||||||
total: 25,
|
total: 25,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
skip: 0,
|
skip: 0,
|
||||||
|
numbers: 10.11,
|
||||||
success: true,
|
success: true,
|
||||||
links: {
|
links: {
|
||||||
previous: undefined,
|
previous: undefined,
|
||||||
@@ -34,6 +71,7 @@ new Vue({
|
|||||||
{
|
{
|
||||||
id: '5968fcad629fa84ab65a5247',
|
id: '5968fcad629fa84ab65a5247',
|
||||||
firstname: 'Ada',
|
firstname: 'Ada',
|
||||||
|
link: 'http://google.com',
|
||||||
lastname: 'Lovelace',
|
lastname: 'Lovelace',
|
||||||
awards: null,
|
awards: null,
|
||||||
known: [
|
known: [
|
||||||
@@ -49,8 +87,8 @@ new Vue({
|
|||||||
the Analytical Engine. She was the first to recognise that the machine had applications beyond pure calculation,
|
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.
|
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.`,
|
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',
|
bornAt: new Date('1815-12-10T00:00:00.000Z'),
|
||||||
diedAt: '1852-11-27T00:00:00.000Z'
|
diedAt: new Date('1852-11-27T00:00:00.000Z')
|
||||||
}, {
|
}, {
|
||||||
id: '5968fcad629fa84ab65a5246',
|
id: '5968fcad629fa84ab65a5246',
|
||||||
firstname: 'Grace',
|
firstname: 'Grace',
|
||||||
@@ -77,8 +115,8 @@ new Vue({
|
|||||||
she was a pioneer of computer programming who invented one of the first compiler related tools.
|
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,
|
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.`,
|
an early high-level programming language still in use today.`,
|
||||||
bornAt: '1815-12-10T00:00:00.000Z',
|
bornAt: new Date('1815-12-10T00:00:00.000Z'),
|
||||||
diedAt: '1852-11-27T00:00:00.000Z'
|
diedAt: new Date('1852-11-27T00:00:00.000Z')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
mode: 'development',
|
||||||
entry: './example/app.js',
|
entry: './example/app.js',
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, '../dist'),
|
path: path.join(__dirname, '../dist'),
|
||||||
@@ -9,7 +11,8 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
devtool: 'cheap-module-source-map',
|
devtool: 'cheap-module-source-map',
|
||||||
devServer: {
|
devServer: {
|
||||||
port: 8081
|
port: 8082,
|
||||||
|
disableHostCheck: true
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.js', '.vue'],
|
extensions: ['.js', '.vue'],
|
||||||
@@ -26,8 +29,8 @@ module.exports = {
|
|||||||
exclude: /node_modules/
|
exclude: /node_modules/
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.s?css$/,
|
||||||
use: ['vue-style-loader', 'css-loader', 'autoprefixer-loader']
|
use: ['vue-style-loader', 'css-loader', 'sass-loader']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||||
@@ -59,5 +62,6 @@ module.exports = {
|
|||||||
template: './example/index.html',
|
template: './example/index.html',
|
||||||
inject: true
|
inject: true
|
||||||
}),
|
}),
|
||||||
|
new VueLoaderPlugin(),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<svg height="16" width="8" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|
||||||
|
<polygon points="0,0 8,8 0,16"
|
||||||
|
style="fill:#666;stroke:purple;stroke-width:0" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 152 B |
+55
-10
@@ -6,13 +6,14 @@ 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'
|
||||||
|
import JsonDate from './types/json-date'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'JsonBox',
|
name: 'JsonBox',
|
||||||
inject: ['expandDepth'],
|
inject: ['expandDepth'],
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: [Object, Array, String, Number, Boolean, Function],
|
type: [Object, Array, String, Number, Boolean, Function, Date],
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
keyName: {
|
keyName: {
|
||||||
@@ -23,20 +24,32 @@ export default {
|
|||||||
depth: {
|
depth: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
}
|
},
|
||||||
|
previewMode: Boolean,
|
||||||
|
forceExpand: Boolean,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
expand: true
|
expand: true,
|
||||||
|
forceExpandMe: this.forceExpand,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.expand = this.depth >= this.expandDepth ? false : true
|
this.expand = this.previewMode || (this.depth >= this.expandDepth ? false : true) || this.forceExpandMe
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggle() {
|
toggle() {
|
||||||
this.expand = !this.expand
|
this.expand = !this.expand
|
||||||
|
|
||||||
|
this.dispatchEvent()
|
||||||
|
},
|
||||||
|
toggleAll() {
|
||||||
|
this.expand = !this.expand
|
||||||
|
this.forceExpandMe = this.expand
|
||||||
|
|
||||||
|
this.dispatchEvent()
|
||||||
|
},
|
||||||
|
dispatchEvent() {
|
||||||
try {
|
try {
|
||||||
this.$el.dispatchEvent(new Event('resized'))
|
this.$el.dispatchEvent(new Event('resized'))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -45,16 +58,29 @@ export default {
|
|||||||
evt.initEvent('resized', true, false)
|
evt.initEvent('resized', true, false)
|
||||||
this.$el.dispatchEvent(evt)
|
this.$el.dispatchEvent(evt)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
getPath() {
|
||||||
|
const path = [this.keyName];
|
||||||
|
let p = this.$parent;
|
||||||
|
while(p.depth) {
|
||||||
|
if (p.$el.classList.contains('jv-node')) {
|
||||||
|
path.push(p.keyName);
|
||||||
|
}
|
||||||
|
p = p.$parent;
|
||||||
|
}
|
||||||
|
return path.reverse()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render (h) {
|
render (h) {
|
||||||
let elements = []
|
let elements = []
|
||||||
let dataType
|
let dataType
|
||||||
|
|
||||||
if (this.value === null || this.value === undefined) {
|
if (this.value === null || this.value === undefined) {
|
||||||
dataType = JsonUndefined
|
dataType = JsonUndefined
|
||||||
} else if (Array.isArray(this.value)) {
|
} else if (Array.isArray(this.value)) {
|
||||||
dataType = JsonArray
|
dataType = JsonArray
|
||||||
|
} else if (Object.prototype.toString.call(this.value) === '[object Date]') {
|
||||||
|
dataType = JsonDate
|
||||||
} else if (typeof this.value === 'object') {
|
} else if (typeof this.value === 'object') {
|
||||||
dataType = JsonObject
|
dataType = JsonObject
|
||||||
} else if (typeof this.value === 'number') {
|
} else if (typeof this.value === 'number') {
|
||||||
@@ -66,15 +92,22 @@ export default {
|
|||||||
} else if (typeof this.value === 'function') {
|
} else if (typeof this.value === 'function') {
|
||||||
dataType = JsonFunction
|
dataType = JsonFunction
|
||||||
}
|
}
|
||||||
|
const complex = this.keyName && (this.value && (Array.isArray(this.value) || (typeof this.value === 'object' && Object.prototype.toString.call(this.value) !== '[object Date]')))
|
||||||
|
|
||||||
if (this.keyName && (this.value && (Array.isArray(this.value) || typeof this.value === 'object'))) {
|
if (!this.previewMode && complex) {
|
||||||
elements.push(h('span', {
|
elements.push(h('span', {
|
||||||
class: {
|
class: {
|
||||||
'jv-toggle': true,
|
'jv-toggle': true,
|
||||||
open: !!this.expand
|
open: !!this.expand
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
click: this.toggle
|
click: (event) => {
|
||||||
|
if (event.altKey) {
|
||||||
|
this.toggleAll()
|
||||||
|
} else {
|
||||||
|
this.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -85,7 +118,7 @@ export default {
|
|||||||
'jv-key': true
|
'jv-key': true
|
||||||
},
|
},
|
||||||
domProps: {
|
domProps: {
|
||||||
innerHTML: `${this.keyName}:`
|
innerText: `${this.keyName}:`
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -99,18 +132,26 @@ export default {
|
|||||||
keyName: this.keyName,
|
keyName: this.keyName,
|
||||||
sort: this.sort,
|
sort: this.sort,
|
||||||
depth: this.depth,
|
depth: this.depth,
|
||||||
expand: this.expand
|
expand: this.expand,
|
||||||
|
previewMode: this.previewMode,
|
||||||
|
forceExpand: this.forceExpandMe
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
'update:expand': value => {
|
'update:expand': value => {
|
||||||
this.expand = value
|
this.expand = value
|
||||||
|
},
|
||||||
|
'update:expandAll': value => {
|
||||||
|
this.expand = value
|
||||||
|
this.forceExpandMe = this.expand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return h('div', {
|
return h('div', {
|
||||||
class: {
|
class: {
|
||||||
'jv-node': true
|
'jv-node': true,
|
||||||
|
'jv-key-node': Boolean(this.keyName) && !complex,
|
||||||
|
'toggle': !this.previewMode && complex
|
||||||
}
|
}
|
||||||
}, elements)
|
}, elements)
|
||||||
}
|
}
|
||||||
@@ -130,6 +171,10 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.toggle {
|
||||||
|
margin-left: 13px !important;
|
||||||
|
}
|
||||||
|
|
||||||
& .jv-node {
|
& .jv-node {
|
||||||
margin-left: 25px;
|
margin-left: 25px;
|
||||||
}
|
}
|
||||||
|
|||||||
+108
-51
@@ -1,28 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="jvClass">
|
<div
|
||||||
|
ref="viewer"
|
||||||
|
:class="jvClass"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
v-if="copyable"
|
v-if="copyable"
|
||||||
class="jv-tooltip"
|
:class="`jv-tooltip ${copyText.align || 'right'}`"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
ref="clip"
|
ref="clip"
|
||||||
class="jv-button"
|
class="jv-button"
|
||||||
:class="{copied}"
|
:class="{copied}"
|
||||||
@click="clip"
|
>
|
||||||
>{{ copied ? 'copied!' : 'copy' }}</span>
|
<slot
|
||||||
|
name="copy"
|
||||||
|
:copied="copied"
|
||||||
|
>
|
||||||
|
{{ copied ? copyText.copiedText : copyText.copyText }}
|
||||||
|
</slot>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="jv-code"
|
class="jv-code"
|
||||||
:class="{'open': expandCode}"
|
:class="{'open': expandCode, boxed}"
|
||||||
>
|
>
|
||||||
<json-box
|
<json-box
|
||||||
ref="jsonBox"
|
ref="jsonBox"
|
||||||
:value="value"
|
:value="value"
|
||||||
:sort="sort"
|
:sort="sort"
|
||||||
|
:preview-mode="previewMode"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="expandableCode"
|
v-if="expandableCode && boxed"
|
||||||
class="jv-more"
|
class="jv-more"
|
||||||
@click="toggleExpandCode"
|
@click="toggleExpandCode"
|
||||||
>
|
>
|
||||||
@@ -38,6 +48,7 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import JsonBox from './json-box'
|
import JsonBox from './json-box'
|
||||||
import Clipboard from 'clipboard'
|
import Clipboard from 'clipboard'
|
||||||
|
import {debounce} from './utils';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'JsonViewer',
|
name: 'JsonViewer',
|
||||||
@@ -49,12 +60,16 @@ export default {
|
|||||||
type: [Object, Array, String, Number, Boolean, Function],
|
type: [Object, Array, String, Number, Boolean, Function],
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
expanded: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
expandDepth: {
|
expandDepth: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 1
|
default: 1
|
||||||
},
|
},
|
||||||
copyable: {
|
copyable: {
|
||||||
type: Boolean,
|
type: [Boolean, Object],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
sort: {
|
sort: {
|
||||||
@@ -69,31 +84,73 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'jv-light'
|
default: 'jv-light'
|
||||||
},
|
},
|
||||||
|
timeformat: {
|
||||||
|
type: Function,
|
||||||
|
default: value => value.toLocaleString(),
|
||||||
|
},
|
||||||
|
previewMode: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
provide () {
|
provide () {
|
||||||
return {
|
return {
|
||||||
expandDepth: this.expandDepth,
|
expandDepth: this.expandDepth,
|
||||||
|
timeformat: this.timeformat,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
copied: false,
|
copied: false,
|
||||||
expandableCode: false,
|
expandableCode: false,
|
||||||
expandCode: false
|
expandCode: this.expanded
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
jvClass () {
|
jvClass() {
|
||||||
return 'jv-container ' + this.theme + (this.boxed ? ' boxed' : '')
|
return 'jv-container ' + this.theme + (this.boxed ? ' boxed' : '')
|
||||||
|
},
|
||||||
|
copyText() {
|
||||||
|
const { copyText, copiedText, timeout, align } = this.copyable
|
||||||
|
|
||||||
|
return {
|
||||||
|
copyText: copyText || 'copy',
|
||||||
|
copiedText: copiedText || 'copied!',
|
||||||
|
timeout: timeout || 2000,
|
||||||
|
align,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value() {
|
||||||
|
this.onResized()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.onResized()
|
this.debounceResized = debounce(this.debResized.bind(this), 200);
|
||||||
this.$el.addEventListener("resized", this.onResized, true)
|
if (this.boxed && this.$refs.jsonBox) {
|
||||||
|
this.onResized()
|
||||||
|
this.$refs.jsonBox.$el.addEventListener("resized", this.onResized, true)
|
||||||
|
}
|
||||||
|
if (this.copyable) {
|
||||||
|
const clipBoard = new Clipboard(this.$refs.clip, {
|
||||||
|
container: this.$refs.viewer,
|
||||||
|
text: () => {
|
||||||
|
return JSON.stringify(this.value, null, 2)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clipBoard.on('success', (e) => {
|
||||||
|
this.onCopied(e)
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onResized () {
|
onResized () {
|
||||||
|
this.debounceResized();
|
||||||
|
},
|
||||||
|
debResized() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
if (!this.$refs.jsonBox) return;
|
||||||
if (this.$refs.jsonBox.$el.clientHeight >= 250) {
|
if (this.$refs.jsonBox.$el.clientHeight >= 250) {
|
||||||
this.expandableCode = true
|
this.expandableCode = true
|
||||||
} else {
|
} else {
|
||||||
@@ -101,25 +158,15 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
clip () {
|
onCopied(copyEvent) {
|
||||||
if (this.copied) {
|
if (this.copied) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
this.copied = true
|
||||||
const clipBoard = new Clipboard(this.$refs.clip, {
|
setTimeout(() => {
|
||||||
text: () => {
|
this.copied = false
|
||||||
return JSON.stringify(this.value, null, 2)
|
}, this.copyText.timeout)
|
||||||
}
|
this.$emit('copied', copyEvent)
|
||||||
})
|
|
||||||
|
|
||||||
clipBoard.on('success', () => {
|
|
||||||
this.copied = true
|
|
||||||
setTimeout(() => {
|
|
||||||
this.copied = false
|
|
||||||
}, 2000)
|
|
||||||
this.$emit('copied')
|
|
||||||
clipBoard.destroy()
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
toggleExpandCode () {
|
toggleExpandCode () {
|
||||||
this.expandCode = !this.expandCode
|
this.expandCode = !this.expandCode
|
||||||
@@ -194,6 +241,10 @@ export default {
|
|||||||
color: #42b983;
|
color: #42b983;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
|
|
||||||
|
.jv-link {
|
||||||
|
color: #0366d6;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.jv-code {
|
.jv-code {
|
||||||
@@ -212,12 +263,15 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.jv-code {
|
.jv-code {
|
||||||
max-height: 300px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 20px;
|
padding: 30px 20px;
|
||||||
|
|
||||||
|
&.boxed {
|
||||||
|
max-height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
&.open {
|
&.open {
|
||||||
max-height: initial;
|
max-height: initial !important;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding-bottom: 45px;
|
padding-bottom: 45px;
|
||||||
@@ -225,25 +279,19 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.jv-toggle {
|
.jv-toggle {
|
||||||
|
background-image: url(./icon.svg);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
background-position: center center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
width: 10px;
|
||||||
&:before {
|
height: 10px;
|
||||||
content: "⏷";
|
margin-right: 2px;
|
||||||
padding: 0px 2px;
|
display: inline-block;
|
||||||
border-radius: 2px;
|
transition: transform 0.1s;
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
&:after {
|
|
||||||
content: " ";
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
width: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.open {
|
&.open {
|
||||||
&:before {
|
transform: rotate(90deg)
|
||||||
content: "⏶";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +312,11 @@ export default {
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
color: #888;
|
color: #888;
|
||||||
transition: all 0.1s;
|
transition: all 0.1s;
|
||||||
// background: red;
|
transform: rotate(90deg);
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
transform: rotate(-90deg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
@@ -278,7 +330,7 @@ export default {
|
|||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
to bottom,
|
to bottom,
|
||||||
rgba(0, 0, 0, 0) 20%,
|
rgba(0, 0, 0, 0) 20%,
|
||||||
rgba(230, 230, 230, 1) 100%
|
rgba(230, 230, 230, 0.3) 100%
|
||||||
);
|
);
|
||||||
transition: all 0.1s;
|
transition: all 0.1s;
|
||||||
}
|
}
|
||||||
@@ -314,8 +366,13 @@ export default {
|
|||||||
|
|
||||||
.jv-tooltip {
|
.jv-tooltip {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 15px;
|
|
||||||
top: 10px;
|
&.right {
|
||||||
|
right: 15px;
|
||||||
|
}
|
||||||
|
&.left {
|
||||||
|
left: 15px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.j-icon {
|
.j-icon {
|
||||||
|
|||||||
+66
-38
@@ -17,23 +17,44 @@ export default {
|
|||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
sort: Boolean,
|
sort: Boolean,
|
||||||
expand: Boolean
|
expand: Boolean,
|
||||||
|
forceExpand: Boolean,
|
||||||
|
previewMode: Boolean,
|
||||||
},
|
},
|
||||||
computed: {
|
data() {
|
||||||
ordered () {
|
return {
|
||||||
let value = this.jsonValue
|
value: []
|
||||||
|
|
||||||
if (!this.sort) {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
return value.sort()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
jsonValue(newVal) {
|
||||||
|
this.setValue(newVal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.setValue(this.jsonValue);
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
setValue(vals, index = 0) {
|
||||||
|
if (index === 0) {
|
||||||
|
this.value = [];
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
if (vals.length > index) {
|
||||||
|
this.value.push(vals[index]);
|
||||||
|
this.setValue(vals, index + 1);
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
toggle() {
|
toggle() {
|
||||||
this.$emit('update:expand', !this.expand)
|
this.$emit('update:expand', !this.expand)
|
||||||
|
this.dispatchEvent();
|
||||||
|
},
|
||||||
|
toggleAll() {
|
||||||
|
this.$emit('update:expandAll', !this.expand)
|
||||||
|
this.dispatchEvent();
|
||||||
|
},
|
||||||
|
dispatchEvent() {
|
||||||
try {
|
try {
|
||||||
this.$el.dispatchEvent(new Event('resized'))
|
this.$el.dispatchEvent(new Event('resized'))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -47,14 +68,20 @@ export default {
|
|||||||
render (h) {
|
render (h) {
|
||||||
let elements = []
|
let elements = []
|
||||||
|
|
||||||
if (!this.keyName) {
|
if (!this.previewMode && !this.keyName) {
|
||||||
elements.push(h('span', {
|
elements.push(h('span', {
|
||||||
class: {
|
class: {
|
||||||
'jv-toggle': true,
|
'jv-toggle': true,
|
||||||
'open': !!this.expand,
|
'open': !!this.expand,
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
click: this.toggle
|
click: (event) => {
|
||||||
|
if (event.altKey) {
|
||||||
|
this.toggleAll()
|
||||||
|
} else {
|
||||||
|
this.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -65,43 +92,44 @@ export default {
|
|||||||
'jv-array': true,
|
'jv-array': true,
|
||||||
},
|
},
|
||||||
domProps: {
|
domProps: {
|
||||||
innerHTML: '['
|
innerText: '['
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
if (this.expand) {
|
||||||
for (let key in this.ordered) {
|
this.value.forEach((value, key) => {
|
||||||
let value = this.ordered[key]
|
elements.push(h(JsonBox, {
|
||||||
|
key,
|
||||||
elements.push(h(JsonBox, {
|
props: {
|
||||||
key,
|
sort: this.sort,
|
||||||
style: {
|
keyName: `${key}`,
|
||||||
display: !this.expand ? 'none' : undefined
|
depth: this.depth + 1,
|
||||||
},
|
value,
|
||||||
props: {
|
previewMode: this.previewMode,
|
||||||
sort: this.sort,
|
forceExpand: this.forceExpand,
|
||||||
// keyName: key,
|
}
|
||||||
depth: this.depth + 1,
|
}))
|
||||||
value,
|
})
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.expand) {
|
if (!this.expand && this.value.length) {
|
||||||
elements.push(h('span', {
|
elements.push(h('span', {
|
||||||
style: {
|
|
||||||
display: this.expand ? 'none' : undefined
|
|
||||||
},
|
|
||||||
class: {
|
class: {
|
||||||
'jv-ellipsis': true,
|
'jv-ellipsis': true,
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
click: this.toggle
|
click: (event) => {
|
||||||
|
if (event.altKey) {
|
||||||
|
this.toggleAll()
|
||||||
|
} else {
|
||||||
|
this.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
attrs: {
|
attrs: {
|
||||||
title: `click to reveal ${this.jsonValue.length} hidden items`
|
title: `click to reveal ${this.value.length} hidden items`
|
||||||
},
|
},
|
||||||
domProps: {
|
domProps: {
|
||||||
innerHTML: '...'
|
innerText: '...'
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -112,7 +140,7 @@ export default {
|
|||||||
'jv-array': true,
|
'jv-array': true,
|
||||||
},
|
},
|
||||||
domProps: {
|
domProps: {
|
||||||
innerHTML: ']'
|
innerText: ']'
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export default {
|
|||||||
'jv-boolean': true,
|
'jv-boolean': true,
|
||||||
},
|
},
|
||||||
domProps: {
|
domProps: {
|
||||||
innerHTML: props.jsonValue.toString()
|
innerText: props.jsonValue.toString()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'JsonDate',
|
||||||
|
inject: ['timeformat'],
|
||||||
|
functional: true,
|
||||||
|
props: {
|
||||||
|
jsonValue: {
|
||||||
|
type: Date,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render (h, { props, injections }) {
|
||||||
|
const value = props.jsonValue;
|
||||||
|
const timeformat = injections.timeformat;
|
||||||
|
|
||||||
|
return h('span', {
|
||||||
|
class: {
|
||||||
|
'jv-item': true,
|
||||||
|
'jv-string': true,
|
||||||
|
},
|
||||||
|
domProps: {
|
||||||
|
innerText: `"${timeformat(value)}"`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -9,13 +9,17 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
render (h, { props }) {
|
render (h, { props }) {
|
||||||
|
const isInteger = Number.isInteger(props.jsonValue)
|
||||||
|
|
||||||
return h('span', {
|
return h('span', {
|
||||||
class: {
|
class: {
|
||||||
'jv-item': true,
|
'jv-item': true,
|
||||||
'jv-number': true,
|
'jv-number': true,
|
||||||
|
'jv-number-integer': isInteger,
|
||||||
|
'jv-number-float': !isInteger,
|
||||||
},
|
},
|
||||||
domProps: {
|
domProps: {
|
||||||
innerHTML: props.jsonValue.toString()
|
innerText: props.jsonValue.toString()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+66
-30
@@ -17,25 +17,51 @@ export default {
|
|||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
expand: Boolean,
|
expand: Boolean,
|
||||||
sort: Boolean
|
forceExpand: Boolean,
|
||||||
|
sort: Boolean,
|
||||||
|
previewMode: Boolean,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
value: {}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
ordered () {
|
ordered () {
|
||||||
if (!this.sort) {
|
if (!this.sort) {
|
||||||
return this.jsonValue
|
return this.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const ordered = {}
|
const ordered = {}
|
||||||
Object.keys(this.jsonValue).sort().forEach(key => {
|
Object.keys(this.value).sort().forEach(key => {
|
||||||
ordered[key] = this.jsonValue[key]
|
ordered[key] = this.value[key]
|
||||||
})
|
})
|
||||||
return ordered
|
return ordered
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
jsonValue(newVal) {
|
||||||
|
this.setValue(newVal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.setValue(this.jsonValue);
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
setValue(val) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.value = val;
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
toggle() {
|
toggle() {
|
||||||
this.$emit('update:expand', !this.expand)
|
this.$emit('update:expand', !this.expand)
|
||||||
|
this.dispatchEvent();
|
||||||
|
},
|
||||||
|
toggleAll() {
|
||||||
|
this.$emit('update:expandAll', !this.expand)
|
||||||
|
this.dispatchEvent();
|
||||||
|
},
|
||||||
|
dispatchEvent() {
|
||||||
try {
|
try {
|
||||||
this.$el.dispatchEvent(new Event('resized'))
|
this.$el.dispatchEvent(new Event('resized'))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -49,14 +75,20 @@ export default {
|
|||||||
render (h) {
|
render (h) {
|
||||||
let elements = []
|
let elements = []
|
||||||
|
|
||||||
if (!this.keyName) {
|
if (!this.previewMode && !this.keyName) {
|
||||||
elements.push(h('span', {
|
elements.push(h('span', {
|
||||||
class: {
|
class: {
|
||||||
'jv-toggle': true,
|
'jv-toggle': true,
|
||||||
'open': !!this.expand,
|
'open': !!this.expand,
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
click: this.toggle
|
click: (event) => {
|
||||||
|
if (event.altKey) {
|
||||||
|
this.toggleAll()
|
||||||
|
} else {
|
||||||
|
this.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -67,45 +99,49 @@ export default {
|
|||||||
'jv-object': true,
|
'jv-object': true,
|
||||||
},
|
},
|
||||||
domProps: {
|
domProps: {
|
||||||
innerHTML: '{'
|
innerText: '{'
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
for (let key in this.ordered) {
|
if (this.expand) {
|
||||||
if (this.ordered.hasOwnProperty(key)) {
|
for (let key in this.ordered) {
|
||||||
let value = this.ordered[key]
|
if (this.ordered.hasOwnProperty(key)) {
|
||||||
|
let value = this.ordered[key]
|
||||||
|
|
||||||
elements.push(h(JsonBox, {
|
elements.push(h(JsonBox, {
|
||||||
key,
|
key,
|
||||||
style: {
|
props: {
|
||||||
display: !this.expand ? 'none' : undefined
|
sort: this.sort,
|
||||||
},
|
keyName: key,
|
||||||
props: {
|
depth: this.depth + 1,
|
||||||
sort: this.sort,
|
value,
|
||||||
keyName: key,
|
previewMode: this.previewMode,
|
||||||
depth: this.depth + 1,
|
forceExpand: this.forceExpand,
|
||||||
value,
|
}
|
||||||
}
|
}))
|
||||||
}))
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.expand) {
|
if (!this.expand && Object.keys(this.value).length) {
|
||||||
elements.push(h('span', {
|
elements.push(h('span', {
|
||||||
style: {
|
|
||||||
display: this.expand ? 'none' : undefined
|
|
||||||
},
|
|
||||||
class: {
|
class: {
|
||||||
'jv-ellipsis': true,
|
'jv-ellipsis': true,
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
click: this.toggle
|
click: (event) => {
|
||||||
|
if (event.altKey) {
|
||||||
|
this.toggleAll()
|
||||||
|
} else {
|
||||||
|
this.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
attrs: {
|
attrs: {
|
||||||
title: `click to reveal object content (keys: ${Object.keys(this.ordered).join(', ')})`
|
title: `click to reveal object content (keys: ${Object.keys(this.ordered).join(', ')})`
|
||||||
},
|
},
|
||||||
domProps: {
|
domProps: {
|
||||||
innerHTML: '...'
|
innerText: '...'
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -116,7 +152,7 @@ export default {
|
|||||||
'jv-object': true,
|
'jv-object': true,
|
||||||
},
|
},
|
||||||
domProps: {
|
domProps: {
|
||||||
innerHTML: '}'
|
innerText: '}'
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
+73
-10
@@ -1,23 +1,86 @@
|
|||||||
<script>
|
<script>
|
||||||
|
const REG_LINK = /^\w+:\/\//;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'JsonString',
|
name: 'JsonString',
|
||||||
functional: true,
|
|
||||||
props: {
|
props: {
|
||||||
jsonValue: {
|
jsonValue: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render (h, { props }) {
|
data() {
|
||||||
return h('span', {
|
return {
|
||||||
class: {
|
expand: true,
|
||||||
'jv-item': true,
|
canExtend: false,
|
||||||
'jv-string': true,
|
}
|
||||||
},
|
},
|
||||||
domProps: {
|
mounted() {
|
||||||
innerHTML: `"${props.jsonValue.toString()}"`
|
if (this.$refs.itemRef.offsetHeight > this.$refs.holderRef.offsetHeight) {
|
||||||
|
this.canExtend = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggle() {
|
||||||
|
this.expand = !this.expand;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render (h) {
|
||||||
|
let value = this.jsonValue;
|
||||||
|
const islink = REG_LINK.test(value)
|
||||||
|
let domItem
|
||||||
|
|
||||||
|
if (!this.expand) {
|
||||||
|
domItem = {
|
||||||
|
class: {
|
||||||
|
'jv-ellipsis': true,
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
click: this.toggle
|
||||||
|
},
|
||||||
|
domProps: {
|
||||||
|
innerText: '...'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
domItem = {
|
||||||
|
class: {
|
||||||
|
'jv-item': true,
|
||||||
|
'jv-string': true,
|
||||||
|
},
|
||||||
|
ref: 'itemRef',
|
||||||
}
|
}
|
||||||
})
|
if (islink) {
|
||||||
|
value = `<a href="${value}" target="_blank" class="jv-link">${value}</a>`;
|
||||||
|
domItem.domProps = {
|
||||||
|
innerHTML: `"${value.toString()}"`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
domItem.domProps = {
|
||||||
|
innerText: `"${value.toString()}"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return h('span', {}, [
|
||||||
|
this.canExtend && h('span', {
|
||||||
|
class: {
|
||||||
|
'jv-toggle': true,
|
||||||
|
open: this.expand,
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
click: this.toggle,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
h('span', {
|
||||||
|
class: {
|
||||||
|
'jv-holder-node': true,
|
||||||
|
},
|
||||||
|
ref: 'holderRef'
|
||||||
|
}),
|
||||||
|
h('span', domItem)
|
||||||
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default {
|
|||||||
'jv-undefined': true,
|
'jv-undefined': true,
|
||||||
},
|
},
|
||||||
domProps: {
|
domProps: {
|
||||||
innerHTML: props.jsonValue === null ? 'null' : 'undefined'
|
innerText: props.jsonValue === null ? 'null' : 'undefined'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
export const debounce = function(func, wait) {
|
||||||
|
let startTime = Date.now();
|
||||||
|
let timer;
|
||||||
|
|
||||||
|
return (...args) => {
|
||||||
|
if (Date.now() - startTime < wait && timer) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
}
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
func(...args);
|
||||||
|
}, wait);
|
||||||
|
startTime = Date.now();
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
-11619
File diff suppressed because it is too large
Load Diff
+29
-25
@@ -1,33 +1,30 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-json-viewer",
|
"name": "vue-json-viewer",
|
||||||
"version": "2.0.2",
|
"version": "2.2.20",
|
||||||
"description": "vuejs展示json的组件",
|
"description": "vuejs展示json的组件",
|
||||||
"main": "dist/vue-json-viewer.js",
|
"main": "vue-json-viewer.js",
|
||||||
"files": [
|
"files": ["vue-json-viewer.js", "ssr.js", "style.css"],
|
||||||
"lib/*"
|
|
||||||
],
|
|
||||||
"directories": {
|
"directories": {
|
||||||
"lib": "./lib",
|
"lib": "./lib",
|
||||||
"example": "./example"
|
"example": "./example"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --config ./build/webpack.config.js",
|
"build": "npm run build:browser && npm run build:ssr",
|
||||||
|
"build:browser": "webpack --config ./build/webpack.config.js",
|
||||||
|
"build:ssr": "webpack --config ./build/webpack.ssr.config.js",
|
||||||
"example": "webpack-dev-server --config ./example/build/webpack.dev.conf.js"
|
"example": "webpack-dev-server --config ./example/build/webpack.dev.conf.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/chenfengjw163/vue-json-viewer.git"
|
"url": "git+https://github.com/chenfengjw163/vue-json-viewer.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": ["vue", "json"],
|
||||||
"vue",
|
|
||||||
"json"
|
|
||||||
],
|
|
||||||
"homepage": "https://github.com/chenfengjw163/vue-json-viewer#readme",
|
"homepage": "https://github.com/chenfengjw163/vue-json-viewer#readme",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "陈峰",
|
"name": "陈峰",
|
||||||
"email": "chenfengjw@hotmail.com"
|
"email": "chenfengjw@hotmail.com"
|
||||||
},
|
},
|
||||||
"license": "ISC",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/chenfengjw163/vue-json-viewer/issues"
|
"url": "https://github.com/chenfengjw163/vue-json-viewer/issues"
|
||||||
},
|
},
|
||||||
@@ -42,12 +39,10 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clipboard": "^1.7.1",
|
"clipboard": "^2.0.4"
|
||||||
"vue": "^2.5.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^7.1.5",
|
"autoprefixer": "^7.1.5",
|
||||||
"autoprefixer-loader": "^3.2.0",
|
|
||||||
"babel-core": "^6.26.0",
|
"babel-core": "^6.26.0",
|
||||||
"babel-eslint": "^8.0.1",
|
"babel-eslint": "^8.0.1",
|
||||||
"babel-loader": "^7.1.2",
|
"babel-loader": "^7.1.2",
|
||||||
@@ -57,21 +52,30 @@
|
|||||||
"babel-plugin-transform-vue-jsx": "^3.7.0",
|
"babel-plugin-transform-vue-jsx": "^3.7.0",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"babel-runtime": "^6.26.0",
|
"babel-runtime": "^6.26.0",
|
||||||
"css-loader": "^0.28.7",
|
"css-loader": "^3.0.0",
|
||||||
"eslint": "^5.6.0",
|
"eslint": "^6.0.1",
|
||||||
"eslint-plugin-vue": "^5.0.0-beta.3",
|
"eslint-plugin-vue": "^5.0.0-beta.3",
|
||||||
"file-loader": "^1.1.5",
|
"file-loader": "^1.1.5",
|
||||||
"html-webpack-plugin": "^2.30.1",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"node-sass": "^4.5.3",
|
"mini-css-extract-plugin": "^0.5.0",
|
||||||
"sass-loader": "^6.0.6",
|
"node-sass": "^4.12.0",
|
||||||
|
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||||
|
"postcss-loader": "^3.0.0",
|
||||||
|
"sass-loader": "^7.1.0",
|
||||||
"style-loader": "^0.19.0",
|
"style-loader": "^0.19.0",
|
||||||
|
"uglifyjs-webpack-plugin": "^2.1.2",
|
||||||
"url-loader": "^0.6.2",
|
"url-loader": "^0.6.2",
|
||||||
"vue-loader": "^13.3.0",
|
"vue": "^2.6.9",
|
||||||
"vue-style-loader": "^3.0.3",
|
"vue-loader": "^15.7.0",
|
||||||
"vue-template-compiler": "^2.5.2",
|
"vue-style-loader": "^4.1.2",
|
||||||
"webpack": "^3.8.1",
|
"vue-template-compiler": "^2.6.9",
|
||||||
"webpack-bundle-analyzer": "^3.0.2",
|
"webpack": "=4.29.6",
|
||||||
"webpack-dev-server": "^2.9.2",
|
"webpack-bundle-analyzer": "^3.3.2",
|
||||||
|
"webpack-cli": "^3.3.11",
|
||||||
|
"webpack-dev-server": "^3.10.3",
|
||||||
"webpack-merge": "^4.1.0"
|
"webpack-merge": "^4.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^2.6.9"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
module.exports = {
|
||||||
|
sourceMap: false,
|
||||||
|
plugins: [
|
||||||
|
require('autoprefixer')({
|
||||||
|
browsers: ['> 1%', 'android >=4', 'ios >=8']
|
||||||
|
})
|
||||||
|
]
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user