Code前端首页关于Code前端联系我们

或者用 yarn

terry 45分钟前 阅读数 7 #Vue

Vue3做项目怎么选和用高效的JSON编辑器?

最近两年,Vue3 成了前端开发的主流框架之一,很多后台管理、可视化配置、mock 数据生成工具类项目,都少不了一个好用的 JSON 编辑器,但问题也来了:市面上的组件库一堆,到底选哪个更适配 Vue3?选好之后怎么快速集成?有没有踩坑指南?还有,能不能自己手写一个轻量级的?今天就从这些实际开发场景出发,跟大家聊透这个事儿。

先搞懂需求:别盲目跟风选“最火”的

很多开发者上来就搜“Vue3 最强 JSON 编辑器”,但其实“强”不一定等于“适合”,得先明确你的项目是哪种类型,核心需求是什么,再去挑组件。

举个常见的场景对比: 如果是做企业级后台管理系统的配置中心,比如配置菜单、表单规则、接口路由这些,那得要能格式化 JSON、语法高亮、错误提示(必须精准到行号甚至字符位)、折叠展开、一键复制/清空、支持只读模式、支持与 Vue3 的响应式数据双向绑定、可能还要支持 JSON Schema 校验——这种场景,功能全、稳定性高的成熟组件是首选。 如果是做个人小工具、轻量级的 mock 测试页、或者移动端 H5 的配置页,那核心需求是轻、加载快、UI 简洁、适配移动端,可能不需要 JSON Schema 校验,甚至折叠展开都可以简化——这种时候,自己手写一个或者选轻量插件库就够了。

这里可以给个通用的需求自检清单,你先对着勾一勾: ✅ 支持语法高亮(这个基本都有,但要注意深色/浅色主题适配) ✅ 支持格式化(缩进可以自定义吗?比如2空格/4空格/制表符) ✅ 支持语法错误提示(是只提示有错误,还是能具体标错哪里、是什么错?字符串缺少右引号在第3行第15列”这种最实用) ✅ 支持折叠/展开节点(数组、对象能不能折叠?有没有“全部折叠/展开”按钮?) ✅ 支持与 Vue3 的 ref/reactive 双向绑定(这一点很多初学者容易忽略,有些组件只能单向展示修改,不会同步到 Vue 的数据里,得自己写监听事件处理) ✅ 支持只读模式(比如配置审核页,不能让审核者随便改) ✅ 支持一键复制、一键清空、一键压缩成单行 ✅ 支持搜索替换(配置项多的时候太有用了) ✅ 支持 JSON Schema 校验(比如要限制配置里的某个字段必须是数组、某个字段必须是数字在0-100之间) ✅ 轻量、加载快、包体积小(个人工具优先考虑) ✅ 移动端适配(H5或小程序内嵌H5优先考虑) ✅ 主题可定制(要和项目的 UI 风格统一)

勾完之后,你心里大概就有数了,接下来选组件就不会乱。

市面上适配Vue3的主流JSON编辑器,逐个拆解优缺点

现在挑三个适配性最高、用得最多的组件库,给大家详细说说,帮你快速做决定。

1 Vue-Json-Edit:企业级场景的“首选万金油”

这个组件可以说是目前 Vue3 后台管理项目里用得最多的,功能非常全,而且已经更新迭代了很久,坑比较少。

它的核心优势有哪些? 第一个是双向绑定超简单:直接用 v-model 绑定你的 ref 或者 reactive 数据就行,不需要额外写 watch 监听组件的输入事件,对新手特别友好。 第二个是语法高亮和错误提示超精准:如果是红色波浪线提示的小问题(比如多余的逗号、引号没闭合),鼠标悬停上去还能看到具体的错误信息,JSON.parse 解析失败:Unexpected token , in JSON at position 42”,而且支持行号显示,定位起来一秒钟的事儿。 第三个是功能按钮配置灵活:可以通过 props 控制每个按钮的显示/隐藏,比如你不需要搜索替换,就可以把 searchReplace 设置成 false,特别贴合企业级后台不同角色的使用需求(比如管理员可以用所有功能,普通编辑只能用格式化、折叠、清空这些)。 第四个是支持 JSON Schema 校验和可视化编辑:JSON Schema 校验可以避免用户输入不符合规范的配置,可视化编辑对于不懂技术的运营人员特别友好——运营不用写代码,直接在可视化面板里填字段、选类型就行,自动生成正确的 JSON,这一点很多其他组件都做不到这么完善。 第五个是主题可定制:官方默认有浅色和深色主题,还可以通过 CSS 变量或者 props 里的 theme 属性自己改颜色,和 Element Plus、Ant Design Vue 这些主流 UI 框架的适配都没问题。

它也有小缺点:包体积稍微有点大,压缩之后大概有 500KB 左右,如果你的项目对包体积要求特别高(比如是首屏加载要求1秒以内的纯前端小工具),可能就不太合适了,还有,它的可视化编辑面板有时候会有一点点卡顿,尤其是配置项特别多、层级特别深的时候,但一般后台管理的配置项不会有那么深的层级,影响不大。

2 Monaco Editor for Vue3:“硬核开发者的专属玩具”

Monaco Editor 是 VS Code 官方开源的编辑器核心,你可以把它理解成“嵌入到网页里的 VS Code 编辑器”,功能极其强大,不仅可以编辑 JSON,还可以编辑 JS、TS、HTML、CSS 等等几乎所有的代码语言。

它的核心优势不用说太多,用过 VS Code 的都懂: 首先是语法高亮、自动补全、错误提示这些功能,比其他任何 JSON 编辑器都要专业——JSON 字段名自动补全、数组和对象的自动闭合引号和括号、自动缩进、实时的语法校验,甚至还有代码片段提示,对于写复杂 JSON 配置的硬核开发者来说,效率会提升很多。 其次是扩展性极强:你可以通过 Monaco Editor 的插件系统,自己添加功能,比如自定义快捷键、自定义语法高亮规则、自定义 JSON Schema、添加代码格式化的其他插件(Prettier 插件,把 JSON 格式化成你想要的样子),这一点是其他 JSON 编辑器比不了的。 第三是支持多种语言模式切换:如果你的项目有时候需要编辑 JSON,有时候需要编辑 JS,有时候需要编辑 YAML,用 Monaco Editor 一个组件就够了,不需要再引入其他编辑器组件,节省包体积(虽然单个 Monaco Editor 压缩之后也有 1MB 左右,但如果要编辑多种语言,反而比引入多个编辑器更省)。

它的缺点也很明显: 第一个是上手门槛有点高:双向绑定不像 Vue-Json-Edit 那么简单,需要自己写很多事件监听和数据同步的逻辑;自定义主题也比其他组件复杂,需要熟悉 Monaco Editor 的 API;如果没有用过 VS Code 的插件开发,添加自定义功能会有点吃力。 第二个是包体积比较大:压缩之后大概 1MB 左右,对首屏加载有要求的项目要慎重考虑。 第三个是没有官方的可视化编辑面板:虽然可以通过第三方插件实现,但插件的稳定性和兼容性不如 Vue-Json-Edit 自带的好,而且需要额外引入插件,又会增加一些包体积。

3 轻量级手写JSON编辑器:个人小工具的“最佳选择”

如果你的项目对包体积要求特别高,或者只是需要一个简单的格式化、高亮、错误提示功能,完全可以自己手写一个轻量级的 JSON 编辑器,不用引入任何第三方组件库,包体积可以控制在 10KB 以内(压缩之后)。

手写轻量级 JSON 编辑器的核心思路是什么? 其实很简单,就是用两个层: 第一个层是文本输入层:用一个 textarea 或者 contenteditable 的 div,让用户可以输入 JSON 文本。 第二个层是高亮展示层:用一个 div,和文本输入层的位置、字体、大小、行高完全一样,背景透明,覆盖在文本输入层上面,然后通过正则表达式把输入的 JSON 文本里的不同部分(比如字符串、数字、布尔值、null、对象键、数组、括号)替换成不同颜色的 span 标签,实现语法高亮。 然后再加上格式化功能:用 JSON.parse 和 JSON.stringify 实现,注意处理 JSON.parse 失败的情况,给用户提示错误。 还要加上错误提示功能:同样是用 JSON.parse 解析,如果解析失败,捕获错误信息,提取错误位置的行号和列号(这里需要注意,不同浏览器的错误信息格式不一样,Chrome 的是“Unexpected token , in JSON at position 42”,Firefox 的是“JSON.parse: unexpected character at line 3 column 15 of the JSON data”,所以要写一个通用的提取函数),然后给对应的行和列标上红色背景。

这里给大家一个简单的手写轻量级 JSON 编辑器的核心代码片段(不用复制,后面会给完整的踩坑版代码优化方向):

// 高亮函数
const highlightJson = (jsonStr) => {
  if (!jsonStr) return '';
  let tempStr = jsonStr
    .replace(/&/g, '&')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;'); // 先转义特殊字符,防止XSS
  return tempStr
    .replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, (match) => {
      let cls = 'json-number';
      if (/^"/.test(match)) {
        if (/:$/.test(match)) {
          cls = 'json-key';
        } else {
          cls = 'json-string';
        }
      } else if (/true|false/.test(match)) {
        cls = 'json-boolean';
      } else if (/null/.test(match)) {
        cls = 'json-null';
      }
      return `<span class="${cls}">${match}</span>`;
    });
};
// 错误位置提取函数
const getErrorPosition = (error) => {
  const message = error.message;
  let line = 1;
  let column = 1;
  if (message.includes('line')) {
    // Firefox 格式
    const lineMatch = message.match(/line (\d+)/);
    const columnMatch = message.match(/column (\d+)/);
    if (lineMatch) line = parseInt(lineMatch[1]);
    if (columnMatch) column = parseInt(columnMatch[1]);
  } else if (message.includes('position')) {
    // Chrome 格式
    const positionMatch = message.match(/position (\d+)/);
    if (positionMatch) {
      const pos = parseInt(positionMatch[1]);
      const lines = tempJsonStr.value.substring(0, pos).split('\n');
      line = lines.length;
      column = lines[lines.length - 1].length + 1;
    }
  }
  return { line, column };
};

手写轻量级 JSON 编辑器的注意事项(也就是踩坑指南): 第一个是文本输入层和高亮展示层的同步问题:一定要让两个层的位置、字体、大小、行高、padding、margin、border 完全一样,否则高亮的位置会和输入的位置对不上;还要让文本输入层的文字颜色是透明的,背景透明,只让用户输入,不让用户看到输入的原始文字,否则会和高亮展示层的文字重叠;还要监听文本输入层的 scroll 事件,让高亮展示层跟着一起滚动,否则滚动之后高亮的位置也会对不上。 第二个是contenteditable vs textarea 的选择问题:contenteditable 的 div 可以支持更复杂的样式,但处理换行、缩进、选中这些问题比较麻烦;textarea 处理换行、缩进、选中这些问题比较简单,但样式固定,而且只能显示纯色的文字(不过没关系,因为我们要让文字透明)——所以一般推荐用 textarea,更稳定。 第三个是XSS 攻击的问题:一定要先转义输入的 JSON 文本里的特殊字符(&、<、>、"、'、/),再做高亮替换,否则如果用户输入了恶意的 HTML 代码(),会被高亮展示层解析成 HTML,导致 XSS 攻击。 第四个是换行和缩进的问题:格式化的时候,JSON.stringify 的第三个参数可以设置缩进,2 空格;文本输入层监听 keydown 事件的时候,如果用户按了 Tab 键,要阻止默认行为(默认是跳到下一个输入框),然后在光标位置插入两个或者四个空格。

以Vue-Json-Edit为例,完整的集成和使用教程

现在以 Vue-Json-Edit 为例,给大家演示一下完整的集成和使用流程,包括安装、引入、配置、双向绑定、主题定制这些核心内容。

1 第一步:安装组件

在你的 Vue3 项目根目录下,打开终端,输入以下命令安装 Vue-Json-Edit:

npm install vue-json-edit --saveyarn add vue-json-edit

2 第二步:全局引入或局部引入组件

如果你的项目里很多地方都要用到 JSON 编辑器,推荐全局引入;如果只有一两个地方用,推荐局部引入,节省包体积。

全局引入

在你的 main.js 或者 main.ts 文件里,添加以下代码:

import { createApp } from 'vue';
import App from './App.vue';
import JsonEditorVue from 'vue-json-edit';
import 'vue-json-edit/dist/vue-json-edit.css';
const app = createApp(App);
app.use(JsonEditorVue);
app.mount('#app');

局部引入

在你要用到 JSON 编辑器的 Vue 文件里,添加以下代码:

<template>
  <div class="container">
    <JsonEditorVue v-model="jsonData" :options="editorOptions" />
  </div>
</template>
<script setup>
import { ref } from 'vue';
import JsonEditorVue from 'vue-json-edit';
import 'vue-json-edit/dist/vue-json-edit.css';
// 初始化响应式 JSON 数据
const jsonData = ref({
  name: '张三',
  age: 25,
  isStudent: false,
  hobbies: ['读书', '跑步', '看电影'],
  address: {
    province: '广东省',
    city: '深圳市',
    district: '南山区',
  },
});
// 配置编辑器选项
const editorOptions = ref({
  mode: 'code', // 编辑器模式:code(代码模式)、tree(树形可视化模式)、form(表单可视化模式)、text(纯文本模式)、preview(预览模式)
  mainMenuBar: true, // 是否显示主菜单栏
  navigationBar: true, // 是否显示导航栏
  statusBar: true, // 是否显示状态栏
  searchReplace: true, // 是否显示搜索替换按钮
  readOnly: false, // 是否只读
  indentation: 2, // 缩进字符数:2或4
  escapeUnicode: false, // 是否转义 Unicode 字符
  theme: 'light', // 主题:light(浅色)、dark(深色)
});
</script>
<style scoped>
.container {
  width: 80%;
  margin: 50px auto;
  height: 600px;
}
</style>

3 第三步:主题定制

如果官方的浅色和深色主题和你的项目 UI 风格不统一,可以通过 CSS 变量自己改主题,比如改成 Element Plus 的蓝色主题:

/* 在你的全局 CSS 文件或者当前 Vue 文件的 style 标签里(去掉 scoped)添加以下代码 */
:root {
  --json-editor-bg: #ffffff;
  --json-editor-border: #e4e7ed;
  --json-editor-text: #303133;
  --json-editor-key: #409eff;
  --json-editor-string: #67c23a;
  --json-editor-number: #e6a23c;
  --json-editor-boolean: #f56c6c;
  --json-editor-null: #909399;
  --json-editor-bracket: #909399;
  --json-editor-highlight: #ecf5ff;
  --json-editor-error-bg: #fef0f0;
  --json-editor-error-border: #f56c6c;
  --json-editor-error-text: #f56c6c;
}

4 第四步:处理JSON Schema校验

如果你的项目需要限制配置项的格式,可以通过 JSON Schema 校验实现,你需要定义一个 JSON Schema,然后在 editorOptions 里添加 schema 属性和 schemaErrorHandler 属性:

// 定义 JSON Schema
const jsonSchema = ref({
  type: 'object',
  required: ['name', 'age'],
  properties: {
    name: {
      type: 'string',
      minLength: 2,
      maxLength: 10,
      description: '姓名,长度在2-10个字符之间',
    },
    age: {
      type: 'integer',
      minimum: 18,
      maximum: 60,
      description: '年龄,必须是18-60之间的整数',
    },
    isStudent: {
      type: 'boolean',
      description: '是否是学生',
    },
    hobbies: {
      type: 'array',
      items: {
        type: 'string',
      },
      minItems: 1,
      description: '爱好,至少选一个',
    },
    address: {
      type: 'object',
      required: ['province', 'city'],
      properties: {
        province: {
          type: 'string',
          description: '省份',
        },
        city: {
          type: 'string',
          description: '城市',
        },
        district: {
          type: 'string',
          description: '区县',
        },
      },
    },
  },
});
// 配置编辑器选项(添加schema和schemaErrorHandler)
const editorOptions = ref({
  mode: 'code',
  mainMenuBar: true,
  navigationBar: true,
  statusBar: true,
  searchReplace: true,
  readOnly: false,
  indentation: 2,
  escapeUnicode: false,
  theme: 'light',
  schema: jsonSchema.value, // 引入 JSON Schema
  schemaErrorHandler: (errors) => {
    console.log('JSON Schema 校验错误:', errors);
    // 这里可以添加你的错误处理逻辑,比如弹出提示框
    alert(`JSON Schema 校验失败,请检查配置项:\n${errors.map(error => error.message).join('\n')}`);
  },
});

写在最后:避坑总结

给大家总结一下 Vue3 项目中使用 JSON 编辑器的常见避坑点: 第一个坑是包体积问题:不要盲目跟风选功能最多的组件,要根据项目需求选,如果是个人小工具,手写一个轻量级的就够了;如果是企业级后台,选 Vue-Json-Edit 就可以;如果是硬核开发者,需要编辑多种语言,选 Monaco Editor。 第二个坑是双向绑定问题:有些组件不能直接用 v-model,需要自己写事件监听和数据同步的逻辑,一定要仔细看组件的官方文档。 第三个坑是文本输入层和高亮展示层的同步问题:如果是手写轻量级的,一定要注意这个问题,否则高亮的位置会和输入的位置对不上。 第四个坑是XSS 攻击的问题:如果是手写轻量级的,一定要先转义输入的 JSON 文本里的特殊字符,再做高亮替换。 第五个坑是JSON Schema 校验的错误处理问题:如果用了 JSON Schema 校验,一定要写好错误处理逻辑,给用户清晰的提示,不要只在控制台打印错误。

希望这篇文章能帮到你,如果你还有其他关于 Vue3 JSON 编辑器的问题,欢迎在评论区留言讨论。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门