Skip to content
uAdmin

UJsonEditor:文本编辑、解析与有效性 ​

UJsonEditor 是 CodeMirror 5 文本编辑器,支持 JSON 语法着色、JSON.parse 校验和格式化。它不提供树形编辑或 JSON Schema 校验。

安装 ​

sh
pnpm add codemirror@^5.65 codemirror-editor-vue3@^2.8
ts
import UJsonEditor from '@uadmin/ui/components/UJsonEditor.vue'

不要从 @uadmin/ui 主入口具名导入。这里使用 CodeMirror 5,不是 @codemirror/* 的新版本包。

完整示例:只保存可解析内容 ​

vue
<script setup lang="ts">
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import UJsonEditor from '@uadmin/ui/components/UJsonEditor.vue'

const props = defineProps<{ save: (value: unknown) => Promise<void> }>()
const { t } = useI18n({
  useScope: 'local',
  messages: {
    'zh-CN': { format: '格式化', save: '保存配置', invalid: '请先修复 JSON 格式' },
    'en-US': { format: 'Format', save: 'Save configuration', invalid: 'Fix JSON syntax first' },
  },
})
const editor = ref<InstanceType<typeof UJsonEditor>>()
const text = ref('{"enabled":true}')
const valid = ref(true)
const saving = ref(false)
async function save() {
  if (!valid.value || !text.value.trim()) return
  saving.value = true
  try {
    await props.save(JSON.parse(text.value))
  } finally {
    saving.value = false
  }
}
</script>

<template>
  <UJsonEditor
    ref="editor"
    v-model="text"
    :height="320"
    @validity-change="value => (valid = value)"
  />
  <p v-if="!valid">{{ t('invalid') }}</p>
  <el-button @click="editor?.format()">{{ t('format') }}</el-button>
  <el-button type="primary" :disabled="!valid || !text.trim()" :loading="saving" @click="save">
    {{ t('save') }}
  </el-button>
</template>

save 是父页面提供的真实持久化函数,错误反馈由应用数据层负责。此例拒绝空白配置,即使编辑器将空白视为有效。

API ​

Prop类型默认 / 行为
modelValueunknown'';字符串原样显示,其它值 JSON.stringify 后显示
heightnumber | string320,传给 CodeMirror 包装组件
readonlybooleanfalse
indentnumber2;对象序列化/格式化缩进与 tabSize
Event参数 / 行为
update:modelValuestring,始终是编辑文本
parsed-change解析成功后的值;空白时为 null;无效输入时不发送
validity-change(valid: boolean, error?: string);错误为 JSON.parse 的原始消息
暴露方法行为
format()格式化当前有效 JSON 并发出更新;无效文本不变
validate(text: string)校验传入文本并发出解析/有效性事件;不会修改编辑器文本

无自定义插槽。

容易忽略的行为 ​

  • 输入可以是对象,输出仍为字符串。不要把同一个 model 当成永久的对象类型;推荐始终持有字符串,在保存处解析。
  • 无效文本不会发送 parsed-change,先前的解析对象可能仍存在。保存时同时检查有效性,或直接解析当前文本,不能无条件保存最后一次成功对象。
  • 空白输入触发 parsed-change(null) 和 validity-change(true),与合法 JSON 文本 null 无法仅凭 parsed-change 区分;业务必填规则自行判断。
  • 初始化会校验一次;用户输入会继续校验。父级单独替换 model 时,当前实现只同步文本,不重新校验错误状态。外部载入后可显式调用 validate(newText),或通过 key 重建组件。
  • 循环引用对象无法序列化,会显示空文本;应在传入前验证数据能否序列化。

相关:业务表格 · HTML 编辑器

Vue 3 · TypeScript · Element Plus