106 votes

Vue js error: le modèle de composant doit contenir exactement un élément racine

Je ne sais pas quelle est l'erreur, jusqu'à présent, je suis en train de tester par le biais du journal de la console pour vérifier les changements après la sélection d'un fichier (pour le téléchargement).

Lorsque j'exécute $ npm run watch, j'obtiens l'erreur suivante:

"Webpack est de regarder les fichiers...

95% émettant

ERREUR: Échec de la compilation avec 1 erreurs
19:42:29

erreur dans l' ./ressources/actifs/js/composants/Fichier.vue

(Émise valeur à la place d'une instance de l'Erreur) Vue la syntaxe du modèle erreur:

Modèle de composant doit contenir exactement un élément racine. Si vous utilisez v-si sur plusieurs éléments, utilisez les touches v-sinon-si de la chaîne d'eux au lieu de cela.

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

Mon Fichier.vue est

<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 

242voto

Bert Evans Points 2415

Vous avez deux éléments racine dans votre modèle.

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

Et vous en avez besoin d'un.

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

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

Essentiellement, dans Vue, vous ne devez avoir qu'un seul élément racine dans vos modèles .

25voto

Charles Bochet Points 49

Pour une réponse plus complète: http://www.compulsivecoders.com/tech/vuejs-component-template-should-contain-exactly-one-root-element/

Mais en gros:

  • Actuellement, un VueJS modèle peut contenir qu'un seul élément racine (à cause de problème de rendu)
  • Dans le cas où vous vraiment besoin d'avoir deux éléments racines parce que le HTML structure ne vous permet pas de créer un emballage élément parent, vous pouvez utiliser la vue-fragment.

Pour l'installer:

npm install vue-fragment

Pour l'utiliser:

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

// or

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

Puis, dans votre composant:

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

21voto

Hamoud Points 1424

Vous devez envelopper tout le code HTML dans un seul élément.

 <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  

8voto

blobmaster Points 816

si, pour une raison quelconque, vous ne voulez pas ajouter un wrapper (dans mon premier cas, c'était pour <tr/> de composants), vous pouvez utiliser un composant fonctionnel.

Au lieu d'avoir un seul components/MyCompo.vue vous aurez quelques fichiers dans un components/MyCompo le dossier :

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

Avec cette structure, la façon dont vous appelez votre composant ne changera pas.

components/MyCompo/index.js contenu du fichier :

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) } )
    ]; 
  }
};

Et si vous avez certains de fonction ou de données utilisés dans les deux modèles, passé en tant que propriétés et c'est tout !

Je vous laisse imaginer la construction de la liste des composants et donc beaucoup de caractéristiques avec ce motif.

7voto

Farwa Saddique Points 11

Modèle de composant doit contenir exactement un élément racine. Si vous êtes à l'aide de v-si sur plusieurs éléments, utilisez les touches v-sinon-si de la chaîne d'eux à la place.

La bonne approche est

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

La mauvaise approche

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

Multi Composants De Racine

Le moyen de contourner le problème est d'utiliser des composants fonctionnels, ils sont des composants où vous devez passer les pas de réactif de données composant ne sera pas regarder pour toute modification des données ainsi que de ne pas mettre à jour elle-même quand quelque chose dans le composant parent changements.

Comme c'est un travail autour de il vient avec un prix, composants fonctionnels n'ont pas de cycle de vie des crochets passé, ils sont en instance moins aussi bien que vous ne peut pas se référer this de plus et tout est passé avec le contexte.

Voici comment vous pouvez créer une simple composante fonctionnelle.

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) {
    // ...
  }
})

Maintenant que nous avons couvert les composants fonctionnels de détail permet de couvrir comment créer des composants de racine, pour cela je vais vous présenter un exemple générique.

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

Maintenant, si nous prenons un coup d'oeil à NavBarRoutes modèle

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

Nous ne pouvons pas faire quelque chose comme cela, nous allons violer seul composant racine de restriction

Solution Faire de cette composante fonctionnelle et l'utilisation de rendu

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

Ici vous avez vous avez créé un multi composant racine, Heureux de codage

Référence pour plus de détails, visitez: https://blog.carbonteq.com/vuejs-create-multi-root-components/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X