vue.js中发生错误(渲染函数返回了多个根节点)

时间:2019-03-03 07:34:57

标签: json api vue.js vue-component

我正在尝试使用vue.js从JSON文件生成html标签(子节点),但是我在控制台中遇到此错误: (从render函数返回的多个根节点。render函数应该返回一个根节点)

error screenshot

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>

2 个答案:

答案 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))
    }, 
    
  • 为JSON中的每个顶部元素生成一个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中。希望这对您有所帮助,即使我看到的答案还很晚。