Vue js错误:组件模板应该只包含一个根元素

时间:2017-07-09 20:04:17

标签: javascript node.js laravel vue.js

我不知道错误是什么,到目前为止,我正在测试控制台日志,以便在选择文件(上传)后检查更改。

当我运行$ npm run watch时,我收到以下错误:

  

" Webpack正在观看文件......

     

95%发光

     

错误编译失败1次   19点42分29秒

     ./resources/assets/js/components/File.vue中的

错误

     

(发出的值而不是Error的实例)Vue模板语法   错误:

     

组件模板应该只包含一个根元素。如果你   在多个元素上使用v-if,使用v-else-if链接它们   代替。

     

@ ./resources/assets/js/components/AvatarUpload.vue 5:2-181 @   ./resources/assets/js/app.js @ multi ./resources/assets/js/app.js   ./resources/assets/sass/app.scss"

我的File.vue是

<template>
        <div class="form-group">
            <label for="avatar" class="control-label">Avatar</label>
            <input type="file" v-on:change="fileChange" id="avatar">
            <div class="help-block">
                Help block here updated 4  ...
            </div>
        </div>

        <div class="col-md-6">
            <input type="hidden" name="avatar_id">
            <img class="avatar" title="Current avatar">
        </div>
</template>

<script>
    export default{
        methods: {
            fileChange(){
                console.log('Test of file input change')
            }
        }
    }
</script>

关于如何解决这个问题的任何想法?究竟是什么错误?

11 个答案:

答案 0 :(得分:85)

模板中有两个根元素。

<div class="form-group">
  ...
</div>
<div class="col-md-6">
  ...
</div>

你需要一个。

<div>
    <div class="form-group">
      ...
    </div>

    <div class="col-md-6">
      ...
    </div>
</div>

基本上in Vue you must have only one root element in your templates

答案 1 :(得分:13)

您需要将所有html包装到一个元素中。

<template>
   <div>
        <div class="form-group">
            <label for="avatar" class="control-label">Avatar</label>
            <input type="file" v-on:change="fileChange" id="avatar">
            <div class="help-block">
                Help block here updated 4  ...
            </div>
        </div>

        <div class="col-md-6">
            <input type="hidden" name="avatar_id">
            <img class="avatar" title="Current avatar">
        </div>
   </div>

</template>

<script>
    export default{
        methods: {
            fileChange(){
                console.log('Test of file input change')
            }
        }
    }
</script>

答案 2 :(得分:6)

如果出于任何原因,您不想添加包装器(在我的第一种情况下,该包装器用于 Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_MLFeatureValue", referenced from: objc-class-ref in logistic_model_8000.o "_OBJC_CLASS_$_MLModel", referenced from: objc-class-ref in logistic_model_8000.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) 组件),则可以使用功能组件。

<tr/>文件夹中只有几个文件,而不是一个components/MyCompo.vue

  • components/MyCompo
  • components/MyCompo/index.js
  • components/MyCompo/File.vue

采用这种结构,您调用组件的方式不会改变。

components/MyCompo/Avatar.vue文件内容:

components/MyCompo/index.js

如果两个模板中都使用了某些功能或数据,则将它们作为属性传递就可以了!

我让您想象使用此模式构建组件列表以及如此多的功能。

答案 3 :(得分:3)

更完整的答案:http://www.compulsivecoders.com/tech/vuejs-component-template-should-contain-exactly-one-root-element/

但基本上:

  • 当前,VueJS模板只能包含一个根元素(由于呈现问题)
  • 在某些情况下,由于HTML结构不允许您创建环绕式父元素而确实需要两个根元素,则可以使用vue-fragment

要安装它:

npm install vue-fragment

要使用它:

import Fragment from 'vue-fragment';
Vue.use(Fragment.Plugin);

// or

import { Plugin } from 'vue-fragment';
Vue.use(Plugin);

然后,在您的组件中:

<template>
  <fragment>
    <tr class="hola">
      ...
    </tr>
    <tr class="hello">
      ...
    </tr>
  </fragment>
</template>

答案 4 :(得分:0)

组件模板应仅包含一个根元素。如果要在多个元素上使用v-if,请改为使用v-else-if链接它们。

正确的方法是

<template>
  <div> <!-- The root -->
    <p></p> 
    <p></p>
  </div>
</template>

错误的方法

<template> <!-- No root Element -->
    <p></p> 
    <p></p>
</template>

多根组件

解决该问题的方法是使用功能组件,这些组件是您不必传递任何反应性数据的组件,这意味着组件将不会监视任何数据更改,也不会在父组件中的某些内容发生更改时自行更新。 / p>

因为这是有代价的工作,所以功能组件没有传递任何生命周期挂钩,它们的实例性也越来越差,因此您无法再引用this,并且所有内容都通过传递上下文。

这是创建简单功能组件的方法。

Vue.component('my-component', {
    // you must set functional as true
  functional: true,
  // Props are optional
  props: {
    // ...
  },
  // To compensate for the lack of an instance,
  // we are now provided a 2nd context argument.
  render: function (createElement, context) {
    // ...
  }
})

现在,我们已经详细介绍了功能组件,下面将介绍如何创建多根组件,为此,我将向您展示一个通用示例。

<template>
 <ul>
     <NavBarRoutes :routes="persistentNavRoutes"/>
     <NavBarRoutes v-if="loggedIn" :routes="loggedInNavRoutes" />
     <NavBarRoutes v-else :routes="loggedOutNavRoutes" />
 </ul>
</template>

现在,让我们看一下NavBarRoutes模板

<template>
 <li
 v-for="route in routes"
 :key="route.name"
 >
 <router-link :to="route">
 {{ route.title }}
 </router-link>
 </li>
</template>

我们不能做这样的事情,我们将违反单个根组件限制

解决方案 使该组件正常工作并使用渲染

{
functional: true,
render(h, { props }) {
 return props.routes.map(route =>
  <li key={route.name}>
    <router-link to={route}>
      {route.title}
    </router-link>
  </li>
 )
}

在这里,您已经创建了一个多根组件,快乐编码

有关更多详细信息,请访问:https://blog.carbonteq.com/vuejs-create-multi-root-components/

答案 5 :(得分:0)

我很困惑,因为我知道VueJS应该只包含1个根元素,但是我仍然收到同样的“ template语法错误,组件模板应该只包含一个根元素... ”错误。非常简单的组件。原来我只是将拼写为,这在我复制粘贴的一些文件中也给了我同样的错误。总之,请检查语法以查看组件中的拼写错误。

答案 6 :(得分:0)

代替使用

Vue.component('tabs', {
    template: `
        <div class="tabs">
          <ul>
            <li class="is-active"><a>Pictures</a></li>
            <li><a>Music</a></li>
            <li><a>Videos</a></li>
            <li><a>Documents</a></li>
          </ul>
        </div>

        <div class="tabs-content">
          <slot></slot>
        </div>
    `,
});

您应该使用


Vue.component('tabs', {
    template: `
      <div>
        <div class="tabs">
          <ul>
            <li class="is-active"><a>Pictures</a></li>
            <li><a>Music</a></li>
            <li><a>Videos</a></li>
            <li><a>Documents</a></li>
          </ul>
        </div>

        <div class="tabs-content">
          <slot></slot>
        </div>
      </div>
    `,
});

答案 7 :(得分:0)

只需确保您有一个root div,然后将所有内容放入该root

  <div class="root">
    <!--and put all child here --!>
   <div class='child1'></div>
   <div class='child2'></div>
  </div>

以此类推

答案 8 :(得分:0)

对于 vue 3,他们在模板语法中删除了这个约束:

<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>

但它仍然存在于 JSX 语法中:

不正确的❌

setup(props,{attrs}) {

return ()=>(
     <header>...</header>
     <main  {..attrs}>...</main>
     <footer>...</footer>
)
}

正确✔

setup(props,{attrs}) {

return ()=>(
   <>
     <header>...</header>
     <main  {..attrs}>...</main>
     <footer>...</footer>
   </>
)
}

答案 9 :(得分:0)

除了 Bert 和 blobmaster 的回复:

如果您需要从 DOM 中删除根元素,您可以利用 css 并在根元素上使用 display: value

答案 10 :(得分:0)

有点误导性错误。

解决问题的是我有一个额外的 </div> 没有开口 <div>

我在“div”上使用 Find/Replace 发现了它,它给出了一个奇数。