不使用打包工具构建Vue+JSONForms单页应用时JSONForms标签页空白问题求助
不使用打包工具构建Vue+JSONForms单页应用时JSONForms标签页空白问题求助
我正在尝试不用打包工具,直接通过CDN构建一个集成JSONForms的Vue单页应用。Pre和Table标签页都能正常渲染内容,但JSONForms标签页点击后是空白的。不过如果我故意写错schema(比如把"object"改成"Abject"),页面会报错,这说明JsonForms组件应该是已经注册成功了,但就是不渲染表单内容。
我的代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue JSONForms no bundler</title> </head> <body> <div id="app"> <nav> <a href="#" @click.prevent="currentView = 'my_json_forms'">JSON Forms</a> <a href="#" @click.prevent="currentView = 'my_pre'">Pre</a> <a href="#" @click.prevent="currentView = 'my_table'">Table</a> </nav> <component :is="currentView"></component> </div> <script type="module"> import {createApp, defineComponent} from 'https://cdn.jsdelivr.net/npm/vue/dist/vue.esm-browser.js' import jsonformsvue, {JsonForms} from 'https://cdn.jsdelivr.net/npm/@jsonforms/vue@3.5.1/+esm' import jsonformsvueVanilla, { vanillaRenderers } from 'https://cdn.jsdelivr.net/npm/@jsonforms/vue-vanilla@3.5.1/+esm'; const MyJsonForms = defineComponent({ components: {JsonForms}, template: ` <div> <h2>Home Page</h2> <p>Welcome to the home page.</p> <json-forms :data="data" :renderers="renderers" :schema="schema" :uischema="uischema" @change="onChange" /> </div>` , data() { return { renderers: vanillaRenderers, schema: { type: "object", properties: { name: {type: "string"}, age: {type: "integer"} } }, uischema: { type: "VerticalLayout", elements: [ {type: "Control", scope: "#/properties/name"}, {type: "Control", scope: "#/properties/age"} ] }, data: {name: "John", age: 30} } }, methods: { onChange(event) { this.data = event.data; }, }, }); const MyPre = defineComponent({ template: ` <div> <h2>About Page</h2> <p>This is a simple Vue SPA.</p> <pre>{{ data }}</pre> </div>`, data() { return { data: {name: "John", age: 30} } } }); const MyTable = defineComponent({ template: ` <div> <table> <thead> <tr> <th scope="col">Name</th> <th scope="col">Age</th> </tr> </thead> <tr v-for="(item,idx) in data" data-idx="{{idx}}"> <td>{{ item.name }}</td> <td>{{ item.age }}</td> </tr> </table> </div> `, data() { return { data: [{name: "John", age: 30}] } } }) createApp({ components: { 'my_json_forms': MyJsonForms, 'my_pre': MyPre, 'my_table': MyTable, }, data() { return { currentView: 'home', }; } }).mount('#app'); </script> </body> </html>
问题排查与解决方案
我仔细看了你的代码,找到了几个关键问题:
核心问题:未安装JSONForms Vue插件
你导入了jsonformsvue,但没有在Vue应用中调用app.use(jsonformsvue)来安装这个插件。JSONForms Vue依赖这个插件初始化内部的状态管理、核心服务等依赖项,缺少这一步的话,JsonForms组件无法完成完整的渲染流程,所以会显示空白。次要问题:初始视图指向不存在的组件
你的应用初始currentView设为了'home',但并没有注册对应的home组件,导致页面加载时会先显示空白,虽然点击JSONForms链接能切换视图,但这个小问题可以一起修正。细节优化:动态属性绑定写法错误
MyTable组件里的data-idx="{{idx}}"不符合Vue的动态属性绑定规范,应该改成:data-idx="idx"。
修改后的完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue JSONForms no bundler</title> </head> <body> <div id="app"> <nav> <a href="#" @click.prevent="currentView = 'my_json_forms'">JSON Forms</a> <a href="#" @click.prevent="currentView = 'my_pre'">Pre</a> <a href="#" @click.prevent="currentView = 'my_table'">Table</a> </nav> <component :is="currentView"></component> </div> <script type="module"> import {createApp, defineComponent} from 'https://cdn.jsdelivr.net/npm/vue/dist/vue.esm-browser.js' import jsonformsvue, {JsonForms} from 'https://cdn.jsdelivr.net/npm/@jsonforms/vue@3.5.1/+esm' import jsonformsvueVanilla, { vanillaRenderers } from 'https://cdn.jsdelivr.net/npm/@jsonforms/vue-vanilla@3.5.1/+esm'; const MyJsonForms = defineComponent({ components: {JsonForms}, template: ` <div> <h2>JSON Forms Page</h2> <p>Welcome to the JSON Forms page.</p> <json-forms :data="data" :renderers="renderers" :schema="schema" :uischema="uischema" @change="onChange" /> </div>` , data() { return { renderers: vanillaRenderers, schema: { type: "object", properties: { name: {type: "string"}, age: {type: "integer"} } }, uischema: { type: "VerticalLayout", elements: [ {type: "Control", scope: "#/properties/name"}, {type: "Control", scope: "#/properties/age"} ] }, data: {name: "John", age: 30} } }, methods: { onChange(event) { this.data = event.data; }, }, }); const MyPre = defineComponent({ template: ` <div> <h2>Pre Page</h2> <p>This is a simple Vue SPA.</p> <pre>{{ data }}</pre> </div>`, data() { return { data: {name: "John", age: 30} } } }); const MyTable = defineComponent({ template: ` <div> <h2>Table Page</h2> <table> <thead> <tr> <th scope="col">Name</th> <th scope="col">Age</th> </tr> </thead> <tr v-for="(item,idx) in data" :data-idx="idx"> <td>{{ item.name }}</td> <td>{{ item.age }}</td> </tr> </table> </div> `, data() { return { data: [{name: "John", age: 30}] } } }) const app = createApp({ components: { 'my_json_forms': MyJsonForms, 'my_pre': MyPre, 'my_table': MyTable, }, data() { return { currentView: 'my_json_forms', // 修正初始视图为存在的组件 }; } }) // 安装JSONForms Vue插件,这是核心修复点 app.use(jsonformsvue) app.mount('#app'); </script> </body> </html>
修改后,JSONForms标签页应该就能正常渲染出包含姓名和年龄输入框的表单了,表单的数据变化也能正常同步。
备注:内容来源于stack exchange,提问作者johnmerm
相关产品推荐
相关产品推荐

