wake-up-neo.com

Vue js-Fehler: Die Komponentenvorlage sollte genau ein Stammelement enthalten

Ich weiß nicht, was der Fehler ist. Bisher teste ich das Konsolenprotokoll, um nach der Auswahl einer Datei (zum Hochladen) auf Änderungen zu prüfen.

Wenn ich $ npm run watch starte, erhalte ich die folgende Fehlermeldung:

"Webpack schaut sich die Dateien an ...

95% emittierend 

ERROR Fehler beim Kompilieren mit 1 Fehlern
19:42:29

fehler in ./resources/assets/js/components/File.vue

(Ausgegebener Wert anstelle einer Instanz von Error) Vue-Vorlagensyntax Error:

Die Komponentenvorlage sollte genau ein Stammelement enthalten. Wenn du Verwenden Sie v-if für mehrere Elemente. Verwenden Sie v-else-if, um sie zu verketten stattdessen.

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

Mein File.vue ist

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

Irgendwelche Ideen, wie man das lösen kann? Was ist eigentlich der Fehler?

25
Pathros

Sie haben zwei Stammelemente in Ihrer Vorlage.

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

Und du brauchst eins.

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

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

In Vue haben Sie must nur ein Stammelement in Ihren Vorlagen.

69
Bert

Sie müssen die gesamte HTML-Datei in ein einzelnes Element einschließen.

<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>
13
Hamoud

wenn Sie aus irgendwelchen Gründen keinen Wrapper hinzufügen möchten (in meinem ersten Fall für <tr/>-Komponenten), können Sie eine Funktionskomponente verwenden.

Anstelle eines einzelnen components/MyCompo.vue haben Sie wenige Dateien in einem components/MyCompo-Ordner:

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

Mit dieser Struktur ändert sich die Art und Weise, wie Sie Ihre Komponente aufrufen, nicht.

components/MyCompo/index.js Dateiinhalt:

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

Und wenn in beiden Vorlagen Funktionen oder Daten verwendet werden, werden diese als Eigenschaften übergeben, und das ist es!

Ich lasse Sie sich vorstellen, eine Liste von Komponenten und so viele Funktionen mit diesem Muster zu erstellen.

6
blobmaster

Für eine umfassendere Antwort: http://www.compulsivecoders.com/tech/vuejs-component-template-hould-contain-exactly-one-root-element/

Aber im Grunde:

  • Derzeit kann eine VueJS-Vorlage nur ein Stammelement enthalten (wegen Rendering-Problem).
  • In den Fällen, in denen Sie wirklich zwei Stammelemente benötigen, da Sie in der HTML-Struktur kein übergeordnetes Element erstellen können, können Sie vue-fragment verwenden.

Um es zu installieren:

npm install vue-fragment

Um es zu benutzen:

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

// or

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

Dann in Ihrer Komponente:

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

Ich war verwirrt, da ich wusste, dass VueJS nur 1 Root-Element enthalten sollte und ich dennoch das gleiche "Template-Syntaxfehler) Komponenten-Template sollte genau ein Root-Element enthalten ..." Fehler bei einer extrem einfachen Komponente . Es stellte sich heraus, dass ich gerade </ template> als </ tempate> falsch geschrieben hatte und dass mir in einigen von mir kopierten und eingefügten Dateien derselbe Fehler unterlaufen ist. Überprüfen Sie zusammenfassend Ihre Syntax auf Rechtschreibfehler in Ihrer Komponente.

0

Die Komponentenvorlage sollte genau ein Stammelement enthalten. Wenn Sie v-if für mehrere Elemente verwenden, verwenden Sie stattdessen v-else-if, um diese zu verketten.

Der richtige Ansatz ist

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

Der falsche Ansatz

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

Multi Root-Komponenten

Um dieses Problem zu umgehen, werden funktionale Komponenten verwendet. Hierbei handelt es sich um Komponenten, bei denen keine reaktiven Daten übergeben werden müssen. Das heißt, die Komponente wird nicht auf Datenänderungen achten und sich nicht selbst aktualisieren, wenn sich etwas in der übergeordneten Komponente ändert.

Da dies eine Problemumgehung ist, ist dies mit einem Preis verbunden, bei dem funktionale Komponenten keine Lebenszyklus-Hooks übergeben werden. Sie sind um weniger Beispiele und Sie können sich nicht mehr auf this beziehen und alles wird mit Kontext übergeben.

So erstellen Sie eine einfache Funktionskomponente.

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

Nachdem wir die Funktionskomponenten ausführlich behandelt haben, können wir uns mit der Erstellung von Multi-Root-Komponenten befassen. Dafür werde ich Ihnen ein allgemeines Beispiel vorstellen.

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

Wenn wir uns nun die NavBarRoutes-Vorlage ansehen

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

Wir können so etwas nicht tun, wir werden gegen die Einschränkung der einzelnen Wurzelkomponenten verstoßen

Solution Machen Sie diese Komponente funktionsfähig und verwenden Sie das Rendern

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

Hier haben Sie die Multi-Root-Komponente Happy Coding erstellt

Weitere Informationen finden Sie unter: https://blog.carbonteq.com/vuejs-create-multi-root-components/

0
Farwa Saddique