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 @多./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>

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

Pathros asked 2020-07-29T19:12:57Z
6个解决方案
103 votes

您的模板中有两个根元素。

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

而你需要一个。

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

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

本质上,在Vue中,模板中必须只有一个根元素。

Bert answered 2020-07-29T19:13:15Z
13 votes

您需要将所有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>
Hamoud answered 2020-07-29T19:13:35Z
7 votes

如果出于某种原因,您不想添加包装器(在我的第一种情况下,该包装器用于components/MyCompo.vue组件),则可以使用功能组件。

而不是只有components/MyCompo.vue,在2988229038378078058752文件夹中将只有几个文件:

  • components/MyCompo/index.js
  • components/MyCompo/index.js
  • components/MyCompo/index.js

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

components/MyCompo/index.js文件内容:

import File from './File';
import Avatar from './Avatar';   

const commonSort=(a,b)=>b-a;

export default {
  functional: true,
  name: 'MyCompo',
  props: [ 'someProp', 'plopProp' ],
  render(createElement, context) {
    return [
        createElement( File, { props: Object.assign({light: true, sort: commonSort},context.props) } ),
        createElement( Avatar, { props: Object.assign({light: false, sort: commonSort},context.props) } )
    ]; 
  }
};

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

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

blobmaster answered 2020-07-29T19:14:17Z
6 votes

要获得更完整的答案,请:[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>
Charles Bochet answered 2020-07-29T19:15:03Z
0 votes

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

正确的方法是

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

错误的方法

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

多根组件

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

由于这是要付出代价的工作,因此功能组件没有传递任何生命周期挂钩,它们的实例性也越来越差,您不能再参考2988230520544429029056,并且所有内容都随上下文传递。

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

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/]

Farwa Saddique answered 2020-07-29T19:16:17Z
0 votes

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

armyofda12mnkeys answered 2020-07-29T19:16:37Z
translate from https://stackoverflow.com:/questions/45000510/vue-js-error-component-template-should-contain-exactly-one-root-element