JSONEditor 使用指南

JSONEditor 技术实践指南

JSONEditor 是一个基于 Web 的 JSON 编辑器组件、不需要任何的依赖,由 josdejong 开发维护,支持树形编辑代码编辑纯文本表单视图多种模式,广泛用于后台管理系统、API 调试工具、配置中心等场景。

github:https://github.com/josdejong/jsoneditor

npm:https://www.npmjs.com/package/jsoneditor

cdn:https://www.bootcdn.cn/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: 编辑器不显示,控制台无报错?

相关推荐
2401_865439633 小时前
探索JavaScript对象创建的灵活方式
开发语言·javascript·ecmascript
GISer_Jing3 小时前
从前端到AI Agent工程师:技能升级与职业跃迁指南
前端·人工智能·ai编程
yqcoder3 小时前
遍历的艺术:深入解析 for, for...in, for...of 的核心区别
前端·javascript
IT_陈寒3 小时前
SpringBoot这个事务回滚的坑我算是踩明白了
前端·人工智能·后端
恋猫de小郭3 小时前
Jetbrains 官宣正式发布 KMP 全新默认项目结构,向着 Amper 靠近
android·前端·flutter
xiaoxue..3 小时前
详解:useMemo 和useCallback
前端·react.js·面试
hexu_blog4 小时前
前端vue3后端springboot如何实现图片压缩-免费无限制压缩
前端·java压缩图片·vue压缩图片·批量压缩图片
guslegend4 小时前
第11节:前端 UI 设计与前端基础组件
前端·ui·ai编程
摇滚侠4 小时前
13 移动端 WEB 前端 WEB 开发 HTML5 + CSS3 + 移动 WEB
前端·css3·html5