我正在尝试使用vue.js从JSON文件生成html标签(子节点),但是我在控制台中遇到此错误: (从render函数返回的多个根节点。render函数应该返回一个根节点)
javaScript代码:
const createComponent = (dNode, h) => {
// Handle empty elements and return empty array in case the dNode passed in is empty
if (_.isEmpty(dNode)) {
return [];
}
// if the el is array call createComponent for all elements
if (_.isArray(dNode)) {
return dNode.map((child) => createComponent(child, h))
}
let children = [];
if (dNode.children && dNode.children.length > 0) {
dNode.children.forEach((c) => {
if (_.isString(c)) {
children.push(c)
} else {
children.push(createComponent(c, h))
}
});
}
// Need to clone
const properties = _.cloneDeep(dNode.properties)
return h(dNode.tagName, properties, children.length > 0? children : dNode.textNode)
}
/**
* A sample component uses the recursive createComponent to render a DOM / List of DOM nodes
*/
const MyComponent = Vue.component('my-component', {
render: function (h) {
return createComponent(this.nodes, h)
},
props: {
nodes: {
type: Array,
required: true
}
}
});
new Vue({
el: "#app",
data: {
nodes: []
},
methods: {
getChildrens() {
this.$http.get('nodes.json').then(response => {
this.nodes = response.body;
}, response => {});
}
},
created() {
this.getShortCodes();
this.getChildrens();
}
});
this is nodes.json File Content
[
{
"tagName": "div",
"children": [
{
"tagName": "h1",
"textNode": "Great News"
},
{
"tagName": "h3",
"textNode": "YOU CAN CREATE VUE COMPONENTS OUT OF JSON"
},
{
"tagName": "a",
"properties": {
"attrs": {"href": "#"}
},
"textNode": "Vue.js"
},
{
"tagName": "h2",
"textNode": "Hello from the other side"
}
]
},
{
"tagName": "div",
"children": [
{
"tagName": "h1",
"textNode": "another title"
},
{
"tagName": "h3",
"textNode": "third item"
},
{
"tagName": "a",
"properties": {
"attrs": {"href": "#"}
},
"textNode": "Vue.js"
},
{
"tagName": "h2",
"textNode": "Hello from the other side"
}
]
}
]
This is the vue.js component which i passed nodes as a props
<div id="app">
<div>
<my-component :nodes="nodes"></my-component>
</div>
</div>
答案 0 :(得分:0)
您的createComponent
返回VNodes
行上的9
数组。
return dNode.map((child) => createComponent(child, h))
似乎您总是在组件上传递一组节点定义,因此您正在生成VNodes
的数组,而Vue不希望您在一个组件中具有多个根元素。 / p>
您可以通过以下几种方法:
将数组包装在另一个元素中。像这样:
render: function (h) {
return h('div', {}, createComponent(this.nodes, h))
},
MyComponent
。您还可以更改createComponent
的定义以始终返回单个组件,但这可能会破坏createComponent
的语义,并且您可能无法访问该代码。
答案 1 :(得分:0)
此插件可能可以实现:https://www.npmjs.com/package/vue-fragments
该插件让您可以做一些很酷的事情:
import Fragment from 'vue-fragment'
Vue.use(Fragment.Plugin)
// or
import { Plugin } from 'vue-fragment'
Vue.use(Plugin)
// …
export const MyComponent {
template: '
<fragment>
<input type="text" v-model="message">
<span>{{ message }}</span>
</fragment>
',
data() { return { message: 'hello world }}
}
因此片段本身不会在dom中。希望这对您有所帮助,即使我看到的答案还很晚。