JSONEditor 技术实践指南
JSONEditor 是一个基于 Web 的 JSON 编辑器组件、不需要任何的依赖,由 josdejong 开发维护,支持树形编辑 、代码编辑 、纯文本 、表单视图多种模式,广泛用于后台管理系统、API 调试工具、配置中心等场景。
github:https://github.com/josdejong/jsoneditor
模式概览
JSONEditor 的核心优势在于其提供了 代码编辑 (code) 、纯文本 (text) 、表单视图 (form) 、树形编辑 (tree) 和只读视图 (view) 五种模式,以适应不同的用户角色和编辑需求。
- 树形 (tree) & 表单 (form) 模式 :通过可视化节点和表单控件,极大降低了非技术背景用户(如运营、产品)编辑复杂JSON配置的心理门槛,非常适合后台管理系统 和配置中心。
- 代码 (code) 模式 :提供语法高亮、括号匹配和实时校验,是开发者进行API调试、直接编写和修改JSON结构的首选。
- 纯文本 (text) 模式:适用于处理非标准或大型JSON文本。
- 只读 (view) 模式:用于安全地展示数据,如接口文档示例。
这种多模式设计,使得JSONEditor能够广泛服务于从开发、测试到运营的全流程,成为上述场景中处理JSON数据的通用解决方案。
一、核心
| 特性 | 说明 |
|---|---|
| 多模式切换 | tree(树形)、code(代码)、form(表单)、text(文本)、view(只读) |
| JSON 校验 | 实时语法检查,错误高亮 + 行号定位 |
| 搜索替换 | 支持正则搜索,tree 模式支持 key/value 搜索 |
| 历史撤销 | 内置 undo/redo |
| 排序转换 | 字段排序、JSON ↔ 数组互转 |
| 剪贴板 | 复制/粘贴/剪切节点 |
| 零依赖 | 不依赖任何框架,原生 JS 实现 |
二、引入
npm
bash
npm install jsoneditor
js
import JSONEditor from 'jsoneditor';
import 'jsoneditor/dist/jsoneditor.min.css';
CDN
html
<script src="https://unpkg.com/jsoneditor@10.4.1/dist/jsoneditor.min.js"></script>
<link href="https://unpkg.com/jsoneditor@10.4.1/dist/jsoneditor.min.css" rel="stylesheet">
CDN 加载后,
window.JSONEditor全局可用。
三、快速上手
初始化五步走
js
// 1. 准备容器
const container = document.getElementById('jsoneditor');
// 2. 定义配置
const options = {
mode: 'tree',
modes: ['tree', 'code', 'form', 'text', 'view'],
search: true,
history: true,
};
// 3. 创建编辑器实例
const editor = new JSONEditor(container, options);
// 4. 写入数据
editor.set({
name: 'JSONEditor',
version: '10.4.2',
features: ['tree', 'code', 'validate', 'format'],
config: {
theme: 'default',
readOnly: false,
},
});
// 5. 读取数据
const json = editor.get();
console.log(json);
模板
html
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/jsoneditor@10.4.1/dist/jsoneditor.min.js"></script>
<link href="https://unpkg.com/jsoneditor@10.4.1/dist/jsoneditor.min.css" rel="stylesheet">
<style>
#jsoneditor { width: 100%; height: 500px; }
</style>
</head>
<body>
<div id="jsoneditor"></div>
<button onclick="handleSave()">保存</button>
<script>
const container = document.getElementById('jsoneditor');
const editor = new JSONEditor(container, {
mode: 'code',
modes: ['tree', 'code'],
});
editor.set({ hello: 'world' });
function handleSave() {
const data = editor.get();
console.log('保存的数据:', JSON.stringify(data, null, 2));
}
</script>
</body>
</html>
四、配置项
基础配置
js
const options = {
// 初始模式:tree | code | form | text | view
mode: 'tree',
// 允许用户切换的模式列表
modes: ['tree', 'code', 'form', 'text', 'view'],
// 编辑器名称(多实例时标识)
name: 'configEditor',
};
回调函数
js
const options = {
// JSON 内容变化时触发
onChange: () => {
const json = editor.get();
console.log('内容已变更', json);
},
// 模式切换时触发
onModeChange: (newMode, oldMode) => {
console.log(`模式从 ${oldMode} 切换到 ${newMode}`);
},
// JSON 校验错误时触发
onValidationError: (errors) => {
errors.forEach(err => {
console.error(`校验错误: ${err.message} (位置: ${err.path})`);
});
},
// 编辑器加载完成
onCreateMenu: (menu, node) => {
// 可自定义右键菜单
return menu;
},
};
功能
js
const options = {
search: true, // 搜索框
history: true, // 撤销/重做
navigationBar: true, // 路径导航条
statusBar: true, // 状态栏
mainMenuBar: true, // 顶部主菜单
sortObjectKeys: false, // 按 key 排序
escapeUnicode: false, // 转义 Unicode
enableSort: true, // 允许排序
enableTransform: true, // 允许类型转换
};
只读与限制
js
const options = {
readOnly: false, // 全局只读
limitDragging: false, // 禁止拖拽节点
// 限制编辑深度(超过3层禁止编辑)
onEditable: (node) => {
// node.path 为当前节点路径数组
return node.path.length <= 3;
},
// 限制最大可见节点数(性能保护)
maxVisibleChilds: 100,
};
五、核心 API
数据操作
js
// 设置 JSON --- 替换整个编辑器内容
editor.set({ key: 'value' });
// 获取 JSON --- 返回 JS 对象
const data = editor.get();
// 获取文本 --- 返回格式化后的 JSON 字符串
const text = editor.getText();
// 更新 --- 与现有数据合并(仅 tree 模式)
editor.update({ newKey: 'newValue' });
// 注入新值 --- 替换但不重置撤销历史
editor.updateText('{"fresh": "data"}');
模式切换
js
// 切换到代码模式
editor.setMode('code');
// 获取当前模式
const mode = editor.getMode(); // 'tree' | 'code' | 'form' | 'text' | 'view'
节点操作(tree 模式)
js
// 展开全部节点
editor.expandAll();
// 折叠全部节点
editor.collapseAll();
// 聚焦到指定路径
editor.focus();
// 获取选中节点
const node = editor.getSelection();
// 获取当前可编辑状态
const editable = editor.getEditable();
校验
js
// 手动触发校验
const errors = editor.validate();
errors.forEach(err => {
// err.message --- 错误描述
// err.path --- JSON 路径
// err.line --- 行号(code 模式)
});
销毁
js
// 销毁编辑器实例,释放 DOM 和事件监听
editor.destroy();
六、使用
组件封装
js
<template>
<div ref="container" :style="{ height: height + 'px' }"></div>
</template>
<script>
import JSONEditor from 'jsoneditor';
import 'jsoneditor/dist/jsoneditor.min.css';
export default {
props: {
value: { type: [Object, Array], default: () => ({}) },
mode: { type: String, default: 'tree' },
modes: { type: Array, default: () => ['tree', 'code', 'view'] },
readOnly: { type: Boolean, default: false },
height: { type: Number, default: 400 },
},
data() {
return { editor: null };
},
watch: {
value(val) {
if (val && this.editor) {
this.editor.set(val);
}
},
},
mounted() {
this.editor = new JSONEditor(this.$refs.container, {
mode: this.mode,
modes: this.modes,
onChange: () => {
try {
this.$emit('input', this.editor.get());
} catch (e) {}
},
});
this.editor.set(this.value);
},
beforeDestroy() {
this.editor?.destroy();
},
};
</script>

表单中使用
js
// beforeOpen --- 弹窗打开时初始化
beforeOpen(done, type) {
getDetail(this.form.id).then((res) => {
this.form = res.data.data;
let jsonObj = {};
try { jsonObj = JSON.parse(this.form.value); } catch (e) {}
this.$nextTick(() => {
const container = document.getElementById('jsoneditor');
if (container) {
if (this.editor) this.editor.destroy();
this.editor = new JSONEditor(container, {
mode: type === 'view' ? 'view' : 'code',
modes: ['tree', 'code', 'view'],
search: true,
history: true,
onChange: () => {
try {
this.form.value = JSON.stringify(this.editor.get(), null, 2);
} catch (e) {}
},
});
this.editor.set(jsonObj);
}
});
});
done();
},
// beforeClose --- 关闭时销毁
beforeClose(done) {
if (this.editor) {
this.editor.destroy();
this.editor = null;
}
done();
},
七、各模式对比
| 模式 | 适用场景 | 可编辑 | 特点 |
|---|---|---|---|
| tree | 浏览复杂嵌套结构、对比数据 | ✅ | 可折叠/展开、拖拽排序节点 |
| code | 直接编辑 JSON 源码 | ✅ | 语法高亮、行号、括号匹配 |
| form | 非技术人员填写配置 | ✅ | 表单控件,字段级校验 |
| text | 大文本处理 | ✅ | 纯文本,无高亮 |
| view | 只读展示 | ❌ | 跟 tree 一样的树形,不可编辑 |
八、常见问题
Q: 如何限制用户只使用 tree 模式?
modes: ['tree'],工具条上的模式切换按钮只显示 tree。
Q: 如何设置初始展开深度?
无原生配置,editor.set(data) 后调用 editor.collapseAll() 再手动展开顶层。
Q: onChange 触发太频繁?
用防抖包装:
js
onChange: debounce(() => {
this.form.value = JSON.stringify(this.editor.get(), null, 2);
}, 500),
Q: 如何自定义错误提示语言?
通过 onValidationError 回调自定义错误展示。
javascript
onValidationError: (errors) => {
errors.forEach(err => {
// 自定义错误显示,例如转换为中文提示
alert(`校验错误:${err.message},位置:${err.path}`);
});
}
九、总结
JSONEditor 是 JSON 编辑场景的首选方案------API 简洁、功能完整、零依赖。tree 模式适合浏览复杂数据结构,code 模式适合开发人员直接编写 JSON,view 模式适合只读展示。配合 Vue/React 简单封装即可复用到各个模块。
*[HTML]: Q: 编辑器不显示,控制台无报错?