外观
UJsonEditor:文本编辑、解析与有效性
UJsonEditor 是 CodeMirror 5 文本编辑器,支持 JSON 语法着色、JSON.parse 校验和格式化。它不提供树形编辑或 JSON Schema 校验。
安装
sh
pnpm add codemirror@^5.65 codemirror-editor-vue3@^2.8ts
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 | 类型 | 默认 / 行为 |
|---|---|---|
modelValue | unknown | '';字符串原样显示,其它值 JSON.stringify 后显示 |
height | number | string | 320,传给 CodeMirror 包装组件 |
readonly | boolean | false |
indent | number | 2;对象序列化/格式化缩进与 tabSize |
| Event | 参数 / 行为 |
|---|---|
update:modelValue | string,始终是编辑文本 |
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 重建组件。 - 循环引用对象无法序列化,会显示空文本;应在传入前验证数据能否序列化。