├── .babelrc ├── .editorconfig ├── .eslintgnore ├── .eslintrc.js ├── .gitignore ├── .jsbeautifyrc ├── LICENSE ├── README.md ├── build ├── index.js └── index.js.map ├── dist ├── build.js └── build.js.map ├── index.html ├── index.js ├── mock └── mock.json ├── package.json ├── src ├── App.vue ├── index.js ├── json-view │ ├── index.js │ ├── index.vue │ └── style │ │ ├── index.less │ │ ├── on-dark.less │ │ └── vs-code.less └── main.js ├── static ├── after.jpeg └── before.jpeg ├── test └── jsonview.test.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }], 4 | // "stage-3" 5 | ], 6 | "env": { 7 | "test": { 8 | "presets": [ 9 | ["env", { "targets": { "node": "current" }}] 10 | ] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.{js,jsx,ts,tsx,vue}] 4 | indent_style = space 5 | indent_size = 4 6 | end_of_line = lf 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | -------------------------------------------------------------------------------- /.eslintgnore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /build/ 3 | /dist/ 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true 6 | }, 7 | "extends": "eslint:recommended", 8 | "parserOptions": { 9 | "ecmaVersion": 2018, 10 | "sourceType": "module" 11 | }, 12 | "rules": { 13 | "indent": [ 14 | "error", 15 | "tab" 16 | ], 17 | "linebreak-style": [ 18 | "error", 19 | "windows" 20 | ], 21 | "quotes": [ 22 | "error", 23 | "single" 24 | ], 25 | "semi": [ 26 | "error", 27 | "never" 28 | ] 29 | } 30 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | build/ 4 | npm-debug.log 5 | yarn-error.log 6 | 7 | # Editor directories and files 8 | .idea 9 | *.suo 10 | *.ntvs* 11 | *.njsproj 12 | *.sln 13 | .vscode 14 | .npmignore 15 | _config.yml 16 | 17 | 18 | -------------------------------------------------------------------------------- /.jsbeautifyrc: -------------------------------------------------------------------------------- 1 | { 2 | "brace_style": "collapse,preserve-inline" 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 zhaoxuhui 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **开发背景:** 2 | 3 | 项目开发过程中遇到展示json的场景,且json文件体积过大,小则几百kb,也尝试了已经开源的部分组件,但由于节点过多,渲染速度过慢,无法使用,已有项目技术选型为vue,无法再使用react相关技术,所以考虑自己开发一款。 4 | 5 | 开发过程中参考了react-json-view部分api,组件实现的功能比较基础,但满足基本业务场景,也提供了一些可选配置。 6 | 7 | 即使加载1M左右的json文时,也能实现快速打开 8 | 9 | ### 1.查看示例 10 | [在线示例](https://zhaoxuhui1122.github.io/vue-json-view/) 11 | 12 | ``` 13 | git clone https://github.com/zhaoxuhui1122/vue-json-view.git 14 | npm i 15 | npm run dev 16 | 17 | 或 直接双击index.html 18 | ``` 19 | 20 | 21 | ### 2.在项目中使用 22 | 23 | ``` 24 | npm i -S vue-json-views // 注意是 views 25 | import jsonView from 'vue-json-views' 26 | 27 | 或 28 | 29 | 直接将未编译的组件复制到项目内(推荐该方式,便于自定义修改) 30 | 31 | ``` 32 | 33 | ``` 34 | 37 | 38 | 52 | ``` 53 | 54 | **在非工程化的项目内引用** 55 | 56 | ```html 57 | 58 | 59 | 60 | 61 | 62 | Document 63 | 64 | 65 | 70 | 71 | 72 |
73 | 74 |
75 | 90 | 91 | 92 | ``` 93 | ### 3.可选配置说明 94 | 95 | 属性 | 说明 | 类型 | 默认值 96 | ---|---|---|--- 97 | json|传入的json数据(必填)|Object|- 98 | closed|是否折叠全部|Boolean|false 99 | deep|展开深度,越大渲染速度越慢,建议不超过5|Number|3 100 | icon-style|折叠按钮样式,可选值为square、circle、triangle|String|square 101 | icon-color|两个折叠按钮的颜色|Array|theme=vs-code时,['#c6c6c6', '#c6c6c6'],其他情况为['#747983', '#747983'] 102 | theme|可选主题样式,可选值为one-dark、vs-code,不选时为默认的白色主题|String|- 103 | font-size|字体大小,单位px|Number|14 104 | line-height|行高,单位px|Number|24 105 | 106 | **注:行高和字体大小不建议选用过大值,因为icon大小、每行的padding-left等参数并不会随之发生改变** 107 | 108 | ### 4.关于二次开发 109 | 可根据自己项目的实际情况进行如下开发 110 | - 主题定制:根据需求定制主题,不同的主题名称会给组件定义对应的class名称,根据class重新定义样式即可,可参见项目内的主题配置 111 | - 修改icon样式:项目内icon使用的svg,支持三种样式,可自定义更换或者删除不需要的svg文件,以降低打包体积 112 | - ... 113 | 114 | ### 更新日志 115 | v1.0.0 116 | - 优化加载速度,实现所有节点展开时也能较快加载 117 | 118 | 优化前 119 | ![before](./static/before.jpeg) 120 | 优化后 121 | ![after](./static/after.jpeg) -------------------------------------------------------------------------------- /build/index.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("vue-json-view",[],t):"object"==typeof exports?exports["vue-json-view"]=t():e["vue-json-view"]=t()}("undefined"!=typeof self?self:this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/build/",t(t.s=1)}([function(e,t,n){"use strict";var o=n(9);t.a=o.a},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(2);t.default=o.a},function(e,t,n){"use strict";function o(e){n(3)}var i=n(0),r=n(10),s=n(8),a=o,l=s(i.a,r.a,!1,a,"data-v-613ef595",null);t.a=l.exports},function(e,t,n){var o=n(4);"string"==typeof o&&(o=[[e.i,o,""]]),o.locals&&(e.exports=o.locals);n(6)("3277a7a2",o,!0,{})},function(e,t,n){t=e.exports=n(5)(!1),t.push([e.i,".json-view-container[data-v-613ef595]{background-color:#fff}.json-view-container.deep-1[data-v-613ef595]{padding-right:10px}.json-view-container .json-view[data-v-613ef595]{position:relative;display:block;width:100%;height:100%;white-space:nowrap;padding-left:2rem;box-sizing:border-box;font-family:Consolas!important;cursor:default}.json-view-container .json-view .json-note[data-v-613ef595]{color:#909399;font-size:12px;font-style:italic}.json-view-container .json-view .json-key[data-v-613ef595]{color:#8c6325}.json-view-container .json-view .json-value[data-v-613ef595]{display:inline-block;color:#57b73b;word-break:break-all;white-space:normal}.json-view-container .json-view .json-value.number[data-v-613ef595]{color:#2d8cf0}.json-view-container .json-view .json-value.string[data-v-613ef595]{color:#57b73b}.json-view-container .json-view .json-value.boolean[data-v-613ef595],.json-view-container .json-view .json-value.null[data-v-613ef595]{color:#eb3324}.json-view-container .json-view .json-item[data-v-613ef595]{margin:0;padding-left:2rem;display:flex}.json-view-container .json-view .first-line[data-v-613ef595]{padding:0;margin:0}.json-view-container .json-view .first-line.pointer[data-v-613ef595]{cursor:pointer!important}.json-view-container .json-view .json-body[data-v-613ef595]{position:relative;padding:0;margin:0}.json-view-container .json-view .json-body .base-line[data-v-613ef595]{position:absolute;height:100%;border-left:1px dashed #bbb;top:0;left:2px}.json-view-container .json-view .last-line[data-v-613ef595]{padding:0;margin:0}.json-view-container .json-view .angle[data-v-613ef595]{position:absolute;display:block;cursor:pointer;float:left;width:20px;text-align:center;left:12px}.json-view-container.one-dark[data-v-613ef595]{background-color:#292c33}.json-view-container.one-dark .json-view[data-v-613ef595]{font-family:Menlo,Consolas,Courier New,Courier,FreeMono,monospace!important}.json-view-container.one-dark .json-view .json-note[data-v-613ef595]{color:#909399;font-size:12px;font-style:italic}.json-view-container.one-dark .json-view .json-key[data-v-613ef595]{color:#d27277}.json-view-container.one-dark .json-view .json-value[data-v-613ef595]{color:#c6937c}.json-view-container.one-dark .json-view .json-value.number[data-v-613ef595]{color:#bacdab}.json-view-container.one-dark .json-view .json-value.string[data-v-613ef595]{color:#c6937c}.json-view-container.one-dark .json-view .json-value.boolean[data-v-613ef595],.json-view-container.one-dark .json-view .json-value.null[data-v-613ef595]{color:#659bd1}.json-view-container.one-dark .json-view .first-line[data-v-613ef595]{color:#acb2be}.json-view-container.one-dark .json-view .json-body .base-line[data-v-613ef595]{border-left:1px solid #3c4047}.json-view-container.one-dark .json-view .json-item[data-v-613ef595],.json-view-container.one-dark .json-view .last-line[data-v-613ef595]{color:#acb2be}.json-view-container.vs-code[data-v-613ef595]{background-color:#1e1e1e}.json-view-container.vs-code .json-view[data-v-613ef595]{font-family:Menlo,Consolas,Courier New,Courier,FreeMono,monospace!important}.json-view-container.vs-code .json-view .json-note[data-v-613ef595]{color:#909399;font-size:12px;font-style:italic}.json-view-container.vs-code .json-view .json-key[data-v-613ef595]{color:#a9dbfb}.json-view-container.vs-code .json-view .json-value[data-v-613ef595]{color:#c6937c}.json-view-container.vs-code .json-view .first-line[data-v-613ef595]{color:#d4d4d4}.json-view-container.vs-code .json-view .json-body .base-line[data-v-613ef595]{border-left:1px solid #404040}.json-view-container.vs-code .json-view .json-item[data-v-613ef595],.json-view-container.vs-code .json-view .last-line[data-v-613ef595]{color:#d4d4d4}",""])},function(e,t){function n(e,t){var n=e[1]||"",i=e[3];if(!i)return n;if(t&&"function"==typeof btoa){var r=o(i);return[n].concat(i.sources.map(function(e){return"/*# sourceURL="+i.sourceRoot+e+" */"})).concat([r]).join("\n")}return[n].join("\n")}function o(e){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(e))))+" */"}e.exports=function(e){var t=[];return t.toString=function(){return this.map(function(t){var o=n(t,e);return t[2]?"@media "+t[2]+"{"+o+"}":o}).join("")},t.i=function(e,n){"string"==typeof e&&(e=[[null,e,""]]);for(var o={},i=0;in.parts.length&&(o.parts.length=n.parts.length)}else{for(var s=[],i=0;ithis.deep},isEmptyArrayOrObject:function(e){return[{},[]].map(function(e){return JSON.stringify(e)}).includes(JSON.stringify(e))}},watch:{closed:function(){this.innerclosed=this.closed}}}},function(e,t,n){"use strict";var o=function(){var e=this,t=e.$createElement,n=e._self._c||t;return e.visible?n("div",{class:["json-view-container",e.theme,"deep-"+e.currentDeep]},[n("div",{class:["json-view",e.length?"closeable":""],style:{fontSize:e.fontSize+"px",lineHeight:e.lineHeight+"px"}},[e.length&&"square"===e.iconStyle?n("span",{staticClass:"angle",on:{click:e.toggleClose}},[e.innerclosed?n("svg",{staticStyle:{"vertical-align":"middle",color:"rgb(42, 161, 152)",height:"1em",width:"1em"},attrs:{fill:e.iconColors[0],width:"1em",height:"1em",viewBox:"0 0 1792 1792"}},[n("path",{attrs:{d:"M1344 800v64q0 14-9 23t-23 9h-352v352q0 14-9 23t-23 9h-64q-14 0-23-9t-9-23v-352h-352q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h352v-352q0-14 9-23t23-9h64q14 0 23 9t9 23v352h352q14 0 23 9t9 23zm128 448v-832q0-66-47-113t-113-47h-832q-66 0-113 47t-47 113v832q0 66 47 113t113 47h832q66 0 113-47t47-113zm128-832v832q0 119-84.5 203.5t-203.5 84.5h-832q-119 0-203.5-84.5t-84.5-203.5v-832q0-119 84.5-203.5t203.5-84.5h832q119 0 203.5 84.5t84.5 203.5z"}})]):e._e(),e._v(" "),e.innerclosed?e._e():n("svg",{staticStyle:{"vertical-align":"middle",color:"rgb(88, 110, 117)",height:"1em",width:"1em"},attrs:{fill:e.iconColors[1],width:"1em",height:"1em",viewBox:"0 0 1792 1792"}},[n("path",{attrs:{d:"M1344 800v64q0 14-9 23t-23 9h-832q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h832q14 0 23 9t9 23zm128 448v-832q0-66-47-113t-113-47h-832q-66 0-113 47t-47 113v832q0 66 47 113t113 47h832q66 0 113-47t47-113zm128-832v832q0 119-84.5 203.5t-203.5 84.5h-832q-119 0-203.5-84.5t-84.5-203.5v-832q0-119 84.5-203.5t203.5-84.5h832q119 0 203.5 84.5t84.5 203.5z"}})])]):e._e(),e._v(" "),e.length&&"circle"===e.iconStyle?n("span",{staticClass:"angle",on:{click:e.toggleClose}},[e.innerclosed?e._e():n("svg",{staticStyle:{"vertical-align":"middle",color:"rgb(1, 160, 228)",height:"1em",width:"1em"},attrs:{viewBox:"0 0 24 24",fill:e.iconColors[0],preserveAspectRatio:"xMidYMid meet"}},[n("path",{attrs:{d:"M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M7,13H17V11H7"}})]),e._v(" "),e.innerclosed?n("svg",{staticStyle:{"vertical-align":"middle",color:"rgb(161, 106, 148)",height:"1em",width:"1em"},attrs:{viewBox:"0 0 24 24",fill:e.iconColors[1],preserveAspectRatio:"xMidYMid meet"}},[n("path",{attrs:{d:"M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M13,7H11V11H7V13H11V17H13V13H17V11H13V7Z"}})]):e._e()]):e._e(),e._v(" "),e.length&&"triangle"===e.iconStyle?n("span",{staticClass:"angle",on:{click:e.toggleClose}},[e.innerclosed?e._e():n("svg",{staticStyle:{"vertical-align":"top",color:"#3c4047",height:"1em",width:"1em","padding-left":"2px"},attrs:{viewBox:"0 0 15 15",fill:e.iconColors[0]}},[n("path",{attrs:{d:"M0 5l6 6 6-6z"}})]),e._v(" "),e.innerclosed?n("svg",{staticStyle:{"vertical-align":"top",color:"#3c4047",height:"1em",width:"1em","padding-left":"2px"},attrs:{viewBox:"0 0 15 15",fill:e.iconColors[1]}},[n("path",{attrs:{d:"M0 14l6-6-6-6z"}})]):e._e()]):e._e(),e._v(" "),n("div",{staticClass:"content-wrap"},[n("p",{class:["first-line",e.length>0?"pointer":""],on:{click:e.toggleClose}},[e.jsonKey?n("span",{staticClass:"json-key"},[e._v('"'+e._s(e.jsonKey)+'": ')]):e._e(),e._v(" "),e.length?n("span",[e._v(e._s(e.prefix)+e._s(e.innerclosed?"..."+e.subfix:"")+"\n "),n("span",{staticClass:"json-note"},[e._v(e._s(e.innerclosed?e.length+" items":""))])]):e._e(),e._v(" "),e.length?e._e():n("span",[e._v(e._s((e.isArray?"[]":"{}")+(e.isLast?"":",")))])]),e._v(" "),!e.innerclosed&&e.length?n("div",{staticClass:"json-body"},[e._l(e.items,function(t,o){return[t.isJSON?n("json-view",{key:o,attrs:{closed:e.isClose(),data:t.value,jsonKey:t.key,currentDeep:e.templateDeep+1,deep:e.deep,iconStyle:e.iconStyle,theme:e.theme,fontSize:e.fontSize,lineHeight:e.lineHeight,iconColor:e.iconColors,isLast:o===e.items.length-1,hasSiblings:t.hasSiblings}}):n("p",{key:o,staticClass:"json-item"},[n("span",{staticClass:"json-key"},[e._v(e._s(e.isArray?"":'"'+t.key+'":'))]),e._v(" "),n("span",{class:["json-value",e.getDataType(t.value)]},[e._v("\n "+e._s(("string"===e.getDataType(t.value)?'"':"")+e.formatValue(t.value)+("string"===e.getDataType(t.value)?'"':"")+(o===e.items.length-1?"":","))+"\n ")])])]}),e._v(" "),e.innerclosed?e._e():n("span",{staticClass:"base-line"})],2):e._e(),e._v(" "),e.innerclosed?e._e():n("p",{staticClass:"last-line"},[n("span",[e._v(e._s(e.subfix))])])])])]):e._e()},i=[],r={render:o,staticRenderFns:i};t.a=r}])}); 2 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /build/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 68442870b719a781e9ba","webpack:///index.js","webpack:///src/json-view/index.vue","webpack:///./src/index.js","webpack:///./src/json-view/index.vue","webpack:///./src/json-view/index.vue?365a","webpack:///./src/json-view/index.vue?0e68","webpack:///./node_modules/css-loader/lib/css-base.js","webpack:///./node_modules/vue-style-loader/lib/addStylesClient.js","webpack:///./node_modules/vue-style-loader/lib/listToStyles.js","webpack:///./node_modules/vue-loader/lib/component-normalizer.js","webpack:///./src/json-view/index.js","webpack:///./src/json-view/index.vue?efe9"],"names":["root","factory","exports","module","define","amd","self","this","__webpack_require__","moduleId","installedModules","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","__webpack_exports__","__WEBPACK_IMPORTED_MODULE_0__index__","jsonView","injectStyle","ssrContext","normalizeComponent","__vue_styles__","Component","content","locals","push","cssWithMappingToString","item","useSourceMap","cssMapping","btoa","sourceMapping","toComment","concat","sources","map","source","sourceRoot","join","sourceMap","unescape","encodeURIComponent","JSON","stringify","list","toString","mediaQuery","alreadyImportedModules","length","id","addStylesToDom","styles","domStyle","stylesInDom","refs","j","parts","addStyle","createStyleElement","styleElement","document","createElement","type","head","appendChild","obj","update","remove","querySelector","ssrIdKey","isProduction","noop","parentNode","removeChild","isOldIE","styleIndex","singletonCounter","singletonElement","applyToSingletonTag","bind","applyToTag","newObj","css","media","index","styleSheet","cssText","replaceText","cssNode","createTextNode","childNodes","insertBefore","setAttribute","options","ssrId","firstChild","hasDocument","DEBUG","Error","listToStyles","getElementsByTagName","navigator","test","userAgent","toLowerCase","parentId","_isProduction","_options","newList","mayRemove","textStore","replacement","filter","Boolean","newStyles","part","rawScriptExports","compiledTemplate","functionalTemplate","injectStyles","scopeId","moduleIdentifier","esModule","scriptExports","default","render","staticRenderFns","_compiled","functional","_scopeId","hook","context","$vnode","parent","__VUE_SSR_CONTEXT__","_registeredComponents","add","_ssrRegister","existing","beforeCreate","_injectStyles","h","props","data","Array","required","jsonKey","String","closed","isLast","fontSize","Number","lineHeight","deep","currentDeep","iconStyle","iconColor","theme","hasSiblings","innerclosed","templateDeep","visible","computed","isArray","getDataType","keys","subfix","isEmptyArrayOrObject","prefix","items","json","value","isJSON","isObjectOrArray","key","iconColors","mounted","setTimeout","methods","formatValue","console","log","_isBigNumber","slice","includes","toggleClose","isClose","watch","_vm","_h","$createElement","_c","_self","class","style","staticClass","on","staticStyle","attrs","_e","_v","_s","_l","esExports"],"mappings":"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","file":"index.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"vue-json-view\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"vue-json-view\"] = factory();\n\telse\n\t\troot[\"vue-json-view\"] = factory();\n})(typeof self !== 'undefined' ? self : this, function() {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/build/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 1);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 68442870b719a781e9ba","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"vue-json-view\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"vue-json-view\"] = factory();\n\telse\n\t\troot[\"vue-json-view\"] = factory();\n})(typeof self !== 'undefined' ? self : this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/build/\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 1);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__index__ = __webpack_require__(9);\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n/* harmony default export */ __webpack_exports__[\"a\"] = (__WEBPACK_IMPORTED_MODULE_0__index__[\"a\" /* default */]);\n\n/***/ }),\n/* 1 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__json_view_index_vue__ = __webpack_require__(2);\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__WEBPACK_IMPORTED_MODULE_0__json_view_index_vue__[\"a\" /* default */]);\n\n/***/ }),\n/* 2 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_index_vue__ = __webpack_require__(0);\n/* unused harmony namespace reexport */\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_613ef595_hasScoped_true_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_index_vue__ = __webpack_require__(10);\nfunction injectStyle (ssrContext) {\n __webpack_require__(3)\n}\nvar normalizeComponent = __webpack_require__(8)\n/* script */\n\n\n/* template */\n\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-613ef595\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_index_vue__[\"a\" /* default */],\n __WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_613ef595_hasScoped_true_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_index_vue__[\"a\" /* default */],\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\n/* harmony default export */ __webpack_exports__[\"a\"] = (Component.exports);\n\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n// style-loader: Adds some css to the DOM by adding a \n\n\n\n// WEBPACK FOOTER //\n// src/json-view/index.vue","import jsonView from './json-view/index.vue'\nexport default jsonView\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js","function injectStyle (ssrContext) {\n require(\"!!vue-style-loader!css-loader?minimize!../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-613ef595\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!less-loader!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./index.vue\")\n}\nvar normalizeComponent = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./index.vue\"\nimport __vue_script__ from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./index.vue\"\n/* template */\nimport __vue_template__ from \"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-613ef595\\\",\\\"hasScoped\\\":true,\\\"buble\\\":{\\\"transforms\\\":{}}}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./index.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-613ef595\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_template__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/json-view/index.vue\n// module id = 2\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a 173 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import jsonView from './json-view/index.vue' 2 | export default jsonView 3 | -------------------------------------------------------------------------------- /src/json-view/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'jsonView', 3 | props: { 4 | data: { // 传入的json数据 5 | type: [Object, Array], 6 | required: true 7 | }, 8 | jsonKey: { // json的key值,用于第二层及二层以上的组件的key值 9 | type: String, 10 | default: '' 11 | }, 12 | closed: { // 是否折叠 13 | type: Boolean, 14 | default: false 15 | }, 16 | isLast: { //是否是最后一行 17 | type: Boolean, 18 | default: true 19 | }, 20 | fontSize: { //字体大小 21 | type: Number, 22 | default: 14 23 | }, 24 | lineHeight: { //行高 25 | type: Number, 26 | default: 24 27 | }, 28 | deep: { // 展开深度 29 | type: Number, 30 | default: 3 31 | }, 32 | currentDeep: { // 当前为递归的第几层 33 | type: Number, 34 | default: 1 35 | }, 36 | iconStyle: { // 折叠icon样式 37 | type: String, 38 | default: 'square' 39 | }, 40 | iconColor: { //icon颜色 41 | type: Array, 42 | default() { 43 | return [] 44 | } 45 | }, 46 | theme: { // 主题 47 | type: String, 48 | default: '' 49 | }, 50 | hasSiblings: { // 是否有兄弟节点 51 | type: Boolean, 52 | default: true 53 | } 54 | }, 55 | data() { 56 | return { 57 | innerclosed: this.closed, 58 | templateDeep: this.currentDeep, 59 | visible: false 60 | } 61 | }, 62 | computed: { 63 | isArray() { 64 | return this.getDataType(this.data) === 'array' 65 | }, 66 | length() { 67 | return this.isArray ? this.data.length : Object.keys(this.data).length 68 | }, 69 | subfix() { 70 | const data = this.data 71 | if (this.isEmptyArrayOrObject(data)) { // 如果是空数组或空对象 72 | return '' 73 | } else { 74 | return (this.isArray ? ']' : '}') + (this.isLast ? '' : ',') 75 | } 76 | }, 77 | prefix() { 78 | return this.isArray ? '[' : '{' 79 | }, 80 | items() { 81 | const json = this.data 82 | 83 | if (this.isArray) { 84 | return json.map(item => { 85 | const isJSON = this.isObjectOrArray(item) 86 | return { 87 | value: item, 88 | isJSON, 89 | key: '' 90 | } 91 | }) 92 | } 93 | return Object.keys(json).map(key => { 94 | const item = json[key] 95 | const isJSON = this.isObjectOrArray(item) 96 | return { 97 | value: item, 98 | isJSON, 99 | key 100 | } 101 | }) 102 | }, 103 | iconColors() { 104 | const {theme, iconColor} = this 105 | if (iconColor.length === 2) { 106 | return iconColor 107 | } else { 108 | if (theme === 'one-dark') { 109 | return ['#747983', '#747983'] 110 | } else if (theme === 'vs-code') { 111 | return ['#c6c6c6', '#c6c6c6'] 112 | } else { 113 | return ['#747983', '#747983'] 114 | } 115 | } 116 | } 117 | }, 118 | mounted() { 119 | setTimeout(() => { 120 | this.visible = true 121 | }, 0) 122 | }, 123 | methods: { 124 | formatValue(data) { 125 | if(data && data._isBigNumber) { 126 | return data.toString(10) 127 | } 128 | return data; 129 | }, 130 | getDataType(data) { 131 | return data && data._isBigNumber ? 'number' : Object.prototype.toString.call(data).slice(8, -1).toLowerCase() 132 | }, 133 | isObjectOrArray(source) { 134 | return ['array', 'object'].includes(this.getDataType(source)) 135 | }, 136 | toggleClose() { 137 | if (this.length === 0) { 138 | return 139 | } 140 | if (this.innerclosed) { 141 | this.innerclosed = false 142 | } else { 143 | this.innerclosed = true 144 | } 145 | }, 146 | isClose() { 147 | return this.templateDeep + 1 > this.deep 148 | }, 149 | isEmptyArrayOrObject(data) { // 空数组或者空对象 150 | return [{}, 151 | [] 152 | ].map(item => JSON.stringify(item)).includes(JSON.stringify(data)) 153 | }, 154 | }, 155 | watch: { 156 | closed() { 157 | this.innerclosed = this.closed 158 | } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/json-view/index.vue: -------------------------------------------------------------------------------- 1 | 86 | 91 | 96 | -------------------------------------------------------------------------------- /src/json-view/style/index.less: -------------------------------------------------------------------------------- 1 | // default 2 | 3 | .json-view-container { 4 | background-color: #fff; 5 | &.deep-1{ 6 | // overflow: auto; 7 | padding-right: 10px; 8 | } 9 | .json-view { 10 | position: relative; 11 | display: block; 12 | width: 100%; 13 | height: 100%; 14 | white-space: nowrap; 15 | padding-left: 2rem; 16 | box-sizing: border-box; 17 | font-family: Consolas !important; 18 | cursor: default; 19 | .json-note { 20 | color: #909399; 21 | font-size: 12px; 22 | font-style: italic; 23 | } 24 | 25 | .json-key { 26 | color: #8c6325; 27 | } 28 | 29 | .json-value { 30 | display: inline-block; 31 | color:#57b73b; 32 | word-break: break-all; 33 | white-space: normal; 34 | &.number{ 35 | color: #2d8cf0; 36 | } 37 | &.string{ 38 | color:#57b73b; 39 | } 40 | &.boolean{ 41 | color: #eb3324; 42 | } 43 | &.null{ 44 | color: #eb3324; 45 | } 46 | } 47 | 48 | .json-item { 49 | margin: 0; 50 | padding-left: 2rem; 51 | display: flex; 52 | } 53 | 54 | .first-line { 55 | padding: 0; 56 | margin: 0; 57 | 58 | &.pointer { 59 | cursor: pointer!important; 60 | } 61 | } 62 | 63 | .json-body { 64 | position: relative; 65 | padding: 0; 66 | margin: 0; 67 | 68 | .base-line { 69 | position: absolute; 70 | height: 100%; 71 | border-left: 1px dashed #bbb; 72 | top: 0; 73 | left: 2px; 74 | 75 | &:hover {} 76 | } 77 | } 78 | 79 | .last-line { 80 | padding: 0; 81 | margin: 0; 82 | } 83 | 84 | .angle { 85 | position: absolute; 86 | display: block; 87 | cursor: pointer; 88 | float: left; 89 | width: 20px; 90 | text-align: center; 91 | /*left: ~"calc(2rem - 18px)";*/ 92 | left: 12px; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/json-view/style/on-dark.less: -------------------------------------------------------------------------------- 1 | // vs-code 2 | .json-view-container { 3 | &.one-dark { 4 | background-color: #292c33; 5 | 6 | .json-view { 7 | font-family: Menlo, Consolas, "Courier New", Courier, FreeMono, monospace!important; 8 | 9 | .json-note { 10 | color: #909399; 11 | font-size: 12px; 12 | font-style: italic; 13 | } 14 | 15 | .json-key { 16 | color: #d27277; 17 | } 18 | 19 | .json-value { 20 | color: #c6937c; 21 | &.number{ 22 | color: #bacdab; 23 | } 24 | &.string{ 25 | color:#c6937c; 26 | } 27 | &.boolean{ 28 | color: #659bd1; 29 | } 30 | &.null{ 31 | color: #659bd1 ; 32 | } 33 | } 34 | 35 | .first-line { 36 | color: #acb2be; 37 | } 38 | 39 | .json-body { 40 | .base-line { 41 | border-left: 1px solid #3c4047; 42 | } 43 | } 44 | 45 | .last-line { 46 | color: #acb2be; 47 | } 48 | .json-item{ 49 | color: #acb2be; 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /src/json-view/style/vs-code.less: -------------------------------------------------------------------------------- 1 | 2 | // vs-code 3 | .json-view-container { 4 | &.vs-code { 5 | background-color: #1e1e1e; 6 | .json-view { 7 | font-family: Menlo, Consolas, "Courier New", Courier, FreeMono, monospace !important; 8 | .json-note { 9 | color: #909399; 10 | font-size: 12px; 11 | font-style: italic; 12 | } 13 | 14 | .json-key { 15 | color: #a9dbfb; 16 | } 17 | 18 | .json-value { 19 | color: #c6937c; 20 | } 21 | .first-line { 22 | color: #d4d4d4; 23 | } 24 | 25 | .json-body { 26 | .base-line { 27 | border-left: 1px solid #404040; 28 | } 29 | } 30 | .last-line { 31 | color: #d4d4d4; 32 | } 33 | .json-item{ 34 | color: #d4d4d4; 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | new Vue({ 5 | el: '#app', 6 | render: h => h(App) 7 | }) 8 | -------------------------------------------------------------------------------- /static/after.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoxuhui1122/vue-json-view/97b30c90decf0f65d8e54f5ae083bfdfc6867a36/static/after.jpeg -------------------------------------------------------------------------------- /static/before.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoxuhui1122/vue-json-view/97b30c90decf0f65d8e54f5ae083bfdfc6867a36/static/before.jpeg -------------------------------------------------------------------------------- /test/jsonview.test.js: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import JSONView from '../src/json-view/index.vue'; 3 | 4 | const mockData = require('../mock/mock.json') 5 | 6 | describe('json-view组件测试', () => { 7 | it("设置deep", () => { 8 | const wrapper = mount(JSONView, { 9 | propsData: { 10 | data: {}, 11 | deep: 5 12 | } 13 | }) 14 | expect(wrapper.vm.deep).toEqual(5) 15 | }) 16 | it("设置jsonKey", () => { 17 | const wrapper = mount(JSONView, { 18 | propsData: { 19 | data: {}, 20 | jsonKey: 'jsonKey' 21 | } 22 | }) 23 | expect(wrapper.vm.jsonKey).toEqual('jsonKey') 24 | }) 25 | it("设置closed", () => { 26 | const wrapper = mount(JSONView, { 27 | propsData: { 28 | data: {}, 29 | closed: false 30 | } 31 | }) 32 | expect(wrapper.vm.closed).toEqual(false) 33 | }) 34 | it("设置iconStyle", () => { 35 | const wrapper = mount(JSONView, { 36 | propsData: { 37 | data: {}, 38 | iconStyle: 'circle' 39 | } 40 | }) 41 | expect(wrapper.vm.iconStyle).toEqual('circle') 42 | }) 43 | it("体积为1M的JSON文件,折叠所有节点", () => { 44 | const wrapper = mount(JSONView, { 45 | propsData: { 46 | data: mockData, 47 | closed: true 48 | } 49 | }) 50 | expect(wrapper.vm.closed).toEqual(true) 51 | }) 52 | it("体积为1M的JSON文件,展开深度为1", () => { 53 | const wrapper = mount(JSONView, { 54 | propsData: { 55 | data: mockData, 56 | deep: 1 57 | } 58 | }) 59 | expect(wrapper.vm.deep).toEqual(1) 60 | }) 61 | it("体积为1M的JSON文件,展开深度为2", () => { 62 | const wrapper = mount(JSONView, { 63 | propsData: { 64 | data: mockData, 65 | deep: 2 66 | } 67 | }) 68 | expect(wrapper.vm.deep).toEqual(2) 69 | }) 70 | it("体积为1M的JSON文件,展开深度为3", () => { 71 | const wrapper = mount(JSONView, { 72 | propsData: { 73 | data: mockData, 74 | deep: 3 75 | } 76 | }) 77 | expect(wrapper.vm.deep).toEqual(3) 78 | }) 79 | it("体积为1M的JSON文件,展开深度为4", () => { 80 | const wrapper = mount(JSONView, { 81 | propsData: { 82 | data: mockData, 83 | deep: 4 84 | } 85 | }) 86 | expect(wrapper.vm.deep).toEqual(4) 87 | }) 88 | it("体积为1M的JSON文件,展开深度为5", () => { 89 | const wrapper = mount(JSONView, { 90 | propsData: { 91 | data: mockData, 92 | deep: 5 93 | } 94 | }) 95 | expect(wrapper.vm.deep).toEqual(5) 96 | }) 97 | it("体积为1M的JSON文件,展开深度为6", () => { 98 | const wrapper = mount(JSONView, { 99 | propsData: { 100 | data: mockData, 101 | deep: 6 102 | } 103 | }) 104 | expect(wrapper.vm.deep).toEqual(6) 105 | }) 106 | it("体积为1M的JSON文件,展开深度为10", () => { 107 | const wrapper = mount(JSONView, { 108 | propsData: { 109 | data: mockData, 110 | deep: 10 111 | } 112 | }) 113 | expect(wrapper.vm.deep).toEqual(10) 114 | }) 115 | 116 | }) 117 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | const NODE_ENV = process.env.NODE_ENV; 4 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 5 | 6 | module.exports = { 7 | entry: NODE_ENV === 'npm' ? './src/index.js' : './src/main.js', 8 | output: { 9 | path: path.resolve(__dirname, NODE_ENV === 'npm' ? './build' : './dist'), 10 | publicPath: NODE_ENV === 'npm' ? '/build/' : '/dist/', 11 | filename: NODE_ENV === 'npm' ? 'index.js' : 'build.js', 12 | libraryTarget: 'umd', 13 | library: 'vue-json-view', 14 | umdNamedDefine: true 15 | }, 16 | devtool: NODE_ENV==='develop'?'cheap-module-eval-source-map':'#source-map', 17 | module: { 18 | rules: [{ 19 | test: /\.css$/, 20 | use: [ 21 | 'vue-style-loader', 22 | 'css-loader', 23 | 'less-loader' 24 | ], 25 | }, { 26 | test: /\.vue$/, 27 | loader: 'vue-loader', 28 | options: { 29 | loaders: {} 30 | // other vue-loader options go here 31 | } 32 | }, 33 | { 34 | test: /\.js$/, 35 | loader: 'babel-loader', 36 | exclude: /node_modules/ 37 | }, 38 | { 39 | test: /\.(png|jpg|gif|svg)$/, 40 | loader: 'file-loader', 41 | options: { 42 | name: '[name].[ext]?[hash]' 43 | } 44 | } 45 | ] 46 | }, 47 | resolve: { 48 | alias: { 49 | 'vue$': 'vue/dist/vue.esm.js' 50 | }, 51 | extensions: ['*', '.js', '.vue', '.json'] 52 | }, 53 | devServer: { 54 | historyApiFallback: true, 55 | noInfo: true, 56 | overlay: { 57 | warnings: false, 58 | errors: true 59 | }, 60 | }, 61 | performance: { 62 | hints: false 63 | }, 64 | plugins:[ 65 | new CleanWebpackPlugin() 66 | ] 67 | } 68 | 69 | if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'npm') { 70 | module.exports.plugins = (module.exports.plugins || []).concat([ 71 | new webpack.optimize.UglifyJsPlugin({ 72 | sourceMap: true, 73 | compress: { 74 | warnings: false 75 | } 76 | }), 77 | new webpack.LoaderOptionsPlugin({ 78 | minimize: true 79 | }), 80 | ]) 81 | } 82 | --------------------------------------------------------------------------------