Vue 和 Nuxt 2/3 一体通用 JSON 编辑 & 预览 & 格式化 & 校验工具
English | 简体中文
- 🚀 高性能
- 支持高达 512 MB 的大型 JSON 文档
- 反序列化默认使用 destr,比
JSON.parse
快达 35.96 倍
- 💪 强力
- 预览、编辑、格式化、校验、压缩、排序、查询、过滤、转换、修复、高亮 JSON
- 7 种原始数据类型包括 BigInt and
Symbol
- 3 种编辑模式:文本模式 & 树形模式 & 表格模式
- 2 种主题:浅色主题 & 深色主题
- 双向绑定:parsed 或 stringified JSON
- 🤸 灵活
- Vue 2.6/2.7/3 一体通用
- 支持 SSR,Nuxt 2/3 一体通用
- 支持 Vite,Vue CLI,webpack,CDN...
- 支持微前端
- 支持 PC 端 & 移动端
- 局部注册并传参,或全局注册并传参 (vue-global-config 提供技术支持)
|
|
![]() |
![]() |
npm i json-editor-vue
<script setup>
import JsonEditorVue from 'json-editor-vue'
const value = ref()
</script>
<template>
<JsonEditorVue
v-model="value"
v-bind="{/* 局部 props & attrs */}"
/>
</template>
import JsonEditorVue from 'json-editor-vue'
import { createApp } from 'vue'
createApp()
.use(JsonEditorVue, {
// 全局 props & attrs(单向数据流)
})
.mount('#app')
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<json-editor-vue v-model="value"></json-editor-vue>
</div>
<script type="importmap">
{
"imports": {
"vue": "https://cdn.jsdelivr.net/npm/vue/dist/vue.esm-browser.prod.js",
"vue-demi": "https://cdn.jsdelivr.net/npm/vue-demi/lib/v3/index.mjs",
"vanilla-jsoneditor": "https://cdn.jsdelivr.net/npm/vanilla-jsoneditor",
"json-editor-vue": "https://cdn.jsdelivr.net/npm/[email protected]/dist/json-editor-vue.mjs"
}
}
</script>
<script type="module">
import { createApp, ref } from 'vue'
import JsonEditorVue from 'json-editor-vue'
createApp({
setup: () => ({
value: ref(),
}),
})
.use(JsonEditorVue)
.mount('#app')
</script>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<json-editor-vue v-model="value"></json-editor-vue>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-demi"></script>
<!-- TODO -->
<script src="./vanilla-jsoneditor.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script>
const { createApp, ref } = Vue
createApp({
setup: () => ({
value: ref(),
}),
})
.use(JsonEditorVue)
.mount('#app')
</script>
</body>
</html>
npm i json-editor-vue
<script setup>
import JsonEditorVue from 'json-editor-vue'
const value = ref()
</script>
<template>
<JsonEditorVue
v-model="value"
v-bind="{/* 局部 props & attrs */}"
/>
</template>
import JsonEditorVue from 'json-editor-vue'
import Vue from 'vue'
Vue.use(JsonEditorVue, {
// 全局 props & attrs(单向数据流)
})
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<json-editor-vue v-model="value"></json-editor-vue>
</div>
<script type="importmap">
{
"imports": {
"vue": "https://cdn.jsdelivr.net/npm/vue@2/dist/vue.esm.browser.min.js",
"vue-demi": "https://cdn.jsdelivr.net/npm/vue-demi/lib/v2.7/index.mjs",
"vanilla-jsoneditor": "https://cdn.jsdelivr.net/npm/vanilla-jsoneditor",
"json-editor-vue": "https://cdn.jsdelivr.net/npm/[email protected]/dist/json-editor-vue.mjs"
}
}
</script>
<script type="module">
import Vue from 'vue'
import JsonEditorVue from 'json-editor-vue'
new Vue({
components: { JsonEditorVue },
data() {
return {
value: undefined,
}
},
}).$mount('#app')
</script>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<json-editor-vue v-model="value"></json-editor-vue>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-demi"></script>
<!-- TODO -->
<script src="./vanilla-jsoneditor.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script>
new Vue({
components: { JsonEditorVue },
data() {
return {
value: undefined,
}
},
}).$mount('#app')
</script>
</body>
</html>
npm i @vue/composition-api json-editor-vue
<script>
import VCA from '@vue/composition-api'
import JsonEditorVue from 'json-editor-vue'
import Vue from 'vue'
Vue.use(VCA)
export default {
components: { JsonEditorVue },
data() {
return {
value: undefined,
}
},
}
</script>
<template>
<JsonEditorVue
v-model="value"
v-bind="{/* 局部 props & attrs */}"
/>
</template>
import VCA from '@vue/composition-api'
import JsonEditorVue from 'json-editor-vue'
import Vue from 'vue'
Vue.use(VCA)
Vue.use(JsonEditorVue, {
// 全局 props & attrs(单向数据流)
})
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<json-editor-vue v-model="value"></json-editor-vue>
</div>
<script>
window.process = { env: { NODE_ENV: 'production' } }
</script>
<script type="importmap">
{
"imports": {
"vue": "https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.esm.browser.min.js",
"@vue/composition-api": "https://cdn.jsdelivr.net/npm/@vue/composition-api/dist/vue-composition-api.mjs",
"@vue/composition-api/dist/vue-composition-api.mjs": "https://cdn.jsdelivr.net/npm/@vue/composition-api/dist/vue-composition-api.mjs",
"vue-demi": "https://cdn.jsdelivr.net/npm/vue-demi/lib/v2/index.mjs",
"vanilla-jsoneditor": "https://cdn.jsdelivr.net/npm/vanilla-jsoneditor",
"json-editor-vue": "https://cdn.jsdelivr.net/npm/[email protected]/dist/json-editor-vue.mjs"
}
}
</script>
<script type="module">
import { createApp, ref } from '@vue/composition-api'
import JsonEditorVue from 'json-editor-vue'
const app = createApp({
setup: () => ({
value: ref(),
}),
})
app.use(JsonEditorVue)
app.mount('#app')
</script>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<json-editor-vue v-model="value"></json-editor-vue>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/@vue/composition-api"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-demi"></script>
<!-- TODO -->
<script src="./vanilla-jsoneditor.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script>
const { createApp, ref } = VueCompositionAPI
const app = createApp({
setup: () => ({
value: ref(),
}),
})
app.use(VueCompositionAPI)
app.use(JsonEditorVue)
app.mount('#app')
</script>
</body>
</html>
npm i json-editor-vue
<!-- ~/components/JsonEditorVue.client.vue -->
<script setup>
import JsonEditorVue from 'json-editor-vue'
const attrs = useAttrs()
</script>
<template>
<JsonEditorVue v-bind="attrs" />
</template>
<script setup>
const value = ref()
</script>
<template>
<JsonEditorVue
v-model="value"
v-bind="{/* 局部 props & attrs */}"
/>
</template>
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['json-editor-vue/nuxt'],
})
<script setup>
const value = ref()
</script>
<template>
<JsonEditorVue
v-model="value"
v-bind="{/* 局部 props & attrs */}"
/>
</template>
// ~/plugins/JsonEditorVue.client.ts
import JsonEditorVue from 'json-editor-vue'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(JsonEditorVue, {
// 全局 props & attrs(单向数据流)
})
})
<script setup>
const value = ref()
</script>
<template>
<JsonEditorVue
v-model="value"
v-bind="{/* 局部 props & attrs */}"
/>
</template>
npm i json-editor-vue
// nuxt.config.js
export default {
build: {
// Vite ≥4 (Rollup ≥3) 默认的编译目标为 ES2020
// 所以在 webpack 4 中需要对 Vite ≥4 打包的依赖进行转译
transpile: ['json-editor-vue'],
extend(config) {
// 让 webpack 识别 `.mjs` 文件
config.module.rules.push({
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
})
},
},
}
<script setup>
import { ref } from 'vue'
function JsonEditorVue() {
return process.client
? import('json-editor-vue')
: Promise.resolve({ render: h => h('div') })
}
const value = ref()
</script>
<template>
<JsonEditorVue
v-model="value"
v-bind="{/* 局部 props & attrs */}"
/>
</template>
// nuxt.config.js
export default {
plugins: ['~/plugins/JsonEditorVue.client'],
build: {
// Vite ≥4 (Rollup ≥3) 默认的编译目标为 ES2020
// 所以在 webpack 4 中需要对 Vite ≥4 打包的依赖进行转译
transpile: ['json-editor-vue'],
extend(config) {
// 让 webpack 识别 `.mjs` 文件
config.module.rules.push({
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
})
},
},
}
// ~/plugins/JsonEditorVue.client.js
import JsonEditorVue from 'json-editor-vue'
import Vue from 'vue'
Vue.use(JsonEditorVue, {
// 全局 props & attrs(单向数据流)
})
<script setup>
import { ref } from 'vue'
const value = ref()
</script>
<template>
<ClientOnly>
<JsonEditorVue
v-model="value"
v-bind="{/* 局部 props & attrs */}"
/>
</ClientOnly>
</template>
npm i @vue/composition-api json-editor-vue
// nuxt.config.js
export default {
build: {
// Vite ≥4 (Rollup ≥3) 默认的编译目标为 ES2020
// 所以在 webpack 4 中需要对 Vite ≥4 打包的依赖进行转译
transpile: ['json-editor-vue'],
extend(config) {
// 让 webpack 识别 `.mjs` 文件
config.module.rules.push({
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
})
},
},
}
<script>
import VCA from '@vue/composition-api'
import Vue from 'vue'
Vue.use(VCA)
export default {
components: {
JsonEditorVue: () => process.client
? import('json-editor-vue')
: Promise.resolve({ render: h => h('div') }),
},
data() {
return {
value: undefined,
}
},
}
</script>
<template>
<JsonEditorVue
v-model="value"
v-bind="{/* 局部 props & attrs */}"
/>
</template>
// nuxt.config.js
export default {
plugins: ['~/plugins/JsonEditorVue.client'],
build: {
// Vite ≥4 (Rollup ≥3) 默认的编译目标为 ES2020
// 所以在 webpack 4 中需要对 Vite ≥4 打包的依赖进行转译
transpile: ['json-editor-vue'],
extend(config) {
// 让 webpack 识别 `.mjs` 文件
config.module.rules.push({
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
})
},
},
}
// ~/plugins/JsonEditorVue.client.js
import VCA from '@vue/composition-api'
import JsonEditorVue from 'json-editor-vue'
import Vue from 'vue'
Vue.use(VCA)
Vue.use(JsonEditorVue, {
// 全局 props & attrs(单向数据流)
})
<script>
export default {
data() {
return {
value: undefined,
}
},
}
</script>
<template>
<ClientOnly>
<JsonEditorVue
v-model="value"
v-bind="{/* 局部 props & attrs */}"
/>
</ClientOnly>
</template>
开箱即用
开箱即用
≥ v4.5.15
// vue.config.js
module.exports = {
// Vite ≥4 (Rollup ≥3) 默认的编译目标为 ES2020
// 所以在 webpack 4 中需要对 Vite ≥4 打包的依赖进行转译
transpileDependencies: ['json-editor-vue'],
}
< v4.5.15
// vue.config.js
module.exports = {
// Vite ≥4 (Rollup ≥3) 默认的编译目标为 ES2020
// 所以在 webpack 4 中需要对 Vite ≥4 打包的依赖进行转译
transpileDependencies: ['json-editor-vue'],
configureWebpack: {
module: {
rules: [
// 让 webpack 识别 `.mjs` 文件
{
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
},
],
},
},
}
npm i @babel/plugin-proposal-nullish-coalescing-operator @babel/plugin-proposal-optional-chaining -D
// babel.config.js
module.exports = {
plugins: [
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-proposal-optional-chaining',
],
}
// vue.config.js
module.exports = {
// Vite ≥4 (Rollup ≥3) 默认的编译目标为 ES2020
// 所以在 webpack 4 中需要对 Vite ≥4 打包的依赖进行转译
transpileDependencies: ['json-editor-vue'],
chainWebpack(config) {
// 让 webpack 识别 `.mjs` 文件
config.module
.rule('mjs')
.include
.add(/node_modules/)
.type('javascript/auto')
.end()
},
}
Vue CLI 2 & 1 从 vuejs-templates/webpack 拉取模板
npm i @babel/core@latest @babel/preset-env@latest babel-loader@latest -D
// babel.config.js
module.exports = {
presets: [
'@babel/preset-env',
],
}
// webpack.base.conf.js
module.exports = {
module: {
rules: [
// 让 webpack 识别 `.mjs` 文件
{
test: /\.mjs$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/json-editor-vue')],
},
],
},
}
npm rm json-editor-vue && npm i json-editor-vue
Warning
无法升级大版本号,你可以通过指定依赖版本来升级大版本(如有必要)
// package.json
{
// npm/cnpm/bun
"overrides": {
"vanilla-jsoneditor": "***",
"vue-demi": "***"
},
// yarn/bun
"resolutions": {
"vanilla-jsoneditor": "***",
"vue-demi": "***"
},
// pnpm
"pnpm": {
"overrides": {
"vanilla-jsoneditor": "***",
"vue-demi": "***"
}
}
}
缩小作用范围:
// package.json
{
// npm/cnpm/bun
"overrides": {
"json-editor-vue": {
"vanilla-jsoneditor": "***",
"vue-demi": "***"
}
},
// yarn/bun
"resolutions": {
"json-editor-vue/vanilla-jsoneditor": "***",
"json-editor-vue/vue-demi": "***"
},
// pnpm
"pnpm": {
"overrides": {
"json-editor-vue>vanilla-jsoneditor": "***",
"json-editor-vue>vue-demi": "***"
}
}
}
名称 | 说明 | 类型 | 默认值 |
---|---|---|---|
v-model / modelValue (Vue 3) / value (Vue 2) |
绑定值 | any | |
mode / v-model:mode (Vue 3) / :mode.sync (Vue 2) |
编辑模式 | Mode |
Mode.tree |
debounce | 在 text 模式下输入时更新绑定值的去抖延迟 (毫秒) | number | 300 |
stringified | 在 text 模式下保持绑定值为 stringified JSON | boolean | true |
... | svelte-jsoneditor 的属性 |
- parsed JSON: 就是我们平常所说的 JSON,可以是任何数据类型
- stringified JSON: 序列化后的 JSON,一定是 string 类型
- svelte-jsoneditor:一个包含 parsed JSON 或 stringified JSON 的对象,当作为 stringified JSON 传入时,会经过
JSON.parse
解析 - json-editor-vue:JSON 本身,所见即所得
如果你更倾向于 svelte-jsoneditor 的行为:
<JsonEditorVue
:content="content"
:onChange="(updatedContent) => {
content = updatedContent
}"
/>
Important
输入值与模式无关,除了:
string 类型的输入值在 tree 模式下会被视作普通字符串,在 text 模式下默认会被视作 stringified JSON
tree 模式下的输出值是 parsed JSON,text 模式下的输出值是 stringified JSON
但这个对应关系会被编程式输入或模式切换打破
FAQ: 如何在 text 模式下保持绑定值是 parsed JSON?
Caution
- 对于大型 JSON 文档性能不佳
- 请根据你的 JSON 大小来调整
debounce
的值 - 输入值无效时会输出空
<script setup>
import { Mode } from 'vanilla-jsoneditor'
</script>
<template>
<JsonEditorVue :mode="Mode.text" :stringified="false" />
</template>
标签、属性名称支持驼峰命名和短横线命名
Tip
通过 CDN (HTML) 使用 json-editor-vue 或任何 Vue 组件时,由于 HTML 大小写不敏感,仅能使用短横线命名
仅写上 svelte-jsoneditor 的布尔类型属性如 readOnly
但不传值,会隐式转换为 true
:
-
✓
<JsonEditorVue readOnly />
-
✓
<JsonEditorVue :readOnly="true" />
名称 | 说明 | 类型 |
---|---|---|
jsonEditor | JSONEditor 实例 | object |
<script setup>
import { onMounted, useTemplateRef } from 'vue'
// Vue ≥ v3.5
const jsonEditorVueRef = useTemplateRef('jsonEditorVueRef')
// Vue < v3.5
// const jsonEditorVueRef = ref()
onMounted(() => {
jsonEditorVueRef.value.jsonEditor.focus()
})
</script>
<template>
<JsonEditorVue ref="jsonEditorVueRef" />
</template>
npm i lossless-json
<script setup>
import JsonEditorVue from 'json-editor-vue'
import { parse, stringify } from 'lossless-json'
</script>
<template>
<JsonEditorVue :parser="{ parse, stringify }" />
</template>
<script setup>
import JsonEditorVue from 'json-editor-vue'
import 'vanilla-jsoneditor/themes/jse-theme-dark.css'
</script>
<template>
<JsonEditorVue class="jse-theme-dark" />
</template>
各版本详细改动请参考 release notes
可以通过微信支付帮维护团队买一杯咖啡 💗