Vue+TypeScript中Monaco Editor自定义JSON Schema验证失效求助
无法为基于Monaco Editor的Vue+TS组件添加自定义JSON Schema验证
我正在用Vue.js + TypeScript开发一个基于Monaco Editor的JSON验证组件,目前组件渲染正常,但遇到了一个问题——没办法给Monaco Editor添加自定义Schema验证,输入不符合Schema的JSON内容时不会显示错误提示。
以下是我的实现代码:
父组件 Parent.tsx
data() { const id = 'foo.json'; const validCardSchema = [{ uri: 'http://myserver/foo-schema.json', fileMatch: [id], schema: { type: 'object', properties: { p1: { enum: ['v1', 'v2'] }, p2: { $ref: 'http://myserver/bar-schema.json' } } } }, { uri: 'http://myserver/bar-schema.json', fileMatch: [id], schema: { type: 'object', properties: { q1: { enum: ['x1', 'x2'] } } } }]; return { jsonEditorText: JSON.stringify(editorCode), validCardSchema }; } <TMonacoEditor width="400" height="400" language="json" style="border: none;" code={this.MonacoEditorText} onCodeChange={newVal => this.updateMonacoEditorText(newVal)} />
子组件 child.tsx
createMonaco() { debugger; this.editor = monaco.editor.create(this.$el, this.editorOptions); this.editor.onDidChangeModelContent(event => this.$emit('codeChange', this.editor.getValue()) ); console.log(this.cardSchema); monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ validate: true, schemas: this.cardSchema }); this.monaco = monaco; } }, render(h): VNode { return <div style={this.style} />; }
解决方案
我碰到过类似的问题,几个关键的排查点和修复方法分享给你:
1. 确认Prop传递是否正确
首先看你的父组件,定义的Schema变量是validCardSchema,但子组件里用的是this.cardSchema——你需要确保父组件在传递时把Schema绑定到正确的prop名称上:
// 父组件里修改TMonacoEditor的传参,加上cardSchema <TMonacoEditor width="400" height="400" language="json" style="border: none;" code={this.MonacoEditorText} cardSchema={this.validCardSchema} // 新增这一行 onCodeChange={newVal => this.updateMonacoEditorText(newVal)} />
同时子组件要在props里声明这个属性:
// 子组件的props定义 props: { cardSchema: { type: Array, required: true }, // 其他props... }
2. 确保编辑器模型与Schema的fileMatch匹配
Monaco Editor需要明确知道当前编辑的模型对应哪个Schema,所以要给模型设置正确的URI,和你Schema里fileMatch的id一致:
createMonaco() { this.editor = monaco.editor.create(this.$el, this.editorOptions); // 获取并配置编辑器模型 const model = this.editor.getModel(); if (model) { // 设置模型语言为json monaco.editor.setModelLanguage(model, 'json'); // 设置模型URI,要和Schema里的fileMatch值完全一致 model.setUri(monaco.Uri.parse('foo.json')); } this.editor.onDidChangeModelContent(event => this.$emit('codeChange', this.editor.getValue())); // 配置Schema验证 monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ validate: true, schemas: this.cardSchema }); this.monaco = monaco; }
3. 显式注册Schema(替代setDiagnosticsOptions的方案)
有时候直接用setDiagnosticsOptions可能因为时机问题不生效,你可以尝试逐个注册Schema:
createMonaco() { this.editor = monaco.editor.create(this.$el, this.editorOptions); // 先配置模型URI const model = this.editor.getModel(); if (model) { monaco.editor.setModelLanguage(model, 'json'); model.setUri(monaco.Uri.parse('foo.json')); } // 逐个注册Schema this.cardSchema.forEach(schema => { monaco.languages.json.jsonDefaults.schemaService.registerSchema( schema.uri, schema.fileMatch, schema.schema ); }); // 启用验证 monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ validate: true }); this.editor.onDidChangeModelContent(event => this.$emit('codeChange', this.editor.getValue())); this.monaco = monaco; }
4. 检查$ref的正确性
你的Schema里用了$ref: 'http://myserver/bar-schema.json',要确保这个URI和你注册的第二个Schema的uri完全一致,Monaco才能正确解析引用。
按这几个步骤排查后,应该就能看到Schema验证的错误提示了。
内容的提问来源于stack exchange,提问作者mn10
相关产品推荐
相关产品推荐

