web-dev-qa-db-ja.com

Vue jsエラー:コンポーネントテンプレートにはルート要素を1つだけ含める必要があります

エラーが何なのかわかりませんが、これまでのところ、ファイルを選択した後(アップロード用)に変更を確認するためにコンソールログでテストしています。

$ npm run watchを実行すると、次のエラーが表示されます。

「Webpackはファイルを監視しています…

95%発光

エラー1つのエラーでコンパイルに失敗しました
19:42:29

./resources/assets/js/components/File.vueのエラー

(エラーのインスタンスの代わりに発行された値)Vueテンプレート構文エラー:

コンポーネントテンプレートには、ルート要素を1つだけ含める必要があります。複数の要素で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>

これを解決する方法についてのアイデアはありますか?実際にエラーは何ですか?

38
Pathros

テンプレートには2つのルート要素があります。

<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であなたmustにはテンプレートにルート要素が1つしかありません

98
Bert

すべてのhtmlを1つの要素にラップする必要があります。

<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

何らかの理由でラッパーを追加したくない場合(最初のケースでは<tr/>コンポーネント用)、機能的なコンポーネントを使用できます。

単一のcomponents/MyCompo.vueを持つ代わりに、components/MyCompoフォルダーにいくつかのファイルがあります。

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

この構造により、コンポーネントの呼び出し方法は変わりません。

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

両方のテンプレートで使用される関数またはデータがある場合は、それらをプロパティとして渡し、それだけです!

このパターンを使用して、コンポーネントと非常に多くの機能のリストを作成することを想像してみましょう。

7
blobmaster

より完全な回答: http://www.compulsivecoders.com/tech/vuejs-component-template-should-contain-exactly-one-root-element/

しかし基本的に:

  • 現在、VueJSテンプレートに含めることができるルート要素は1つだけです(レンダリングの問題のため)
  • HTML構造ではラッピングする親要素を作成できないため、2つのルート要素が本当に必要な場合は、 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
Charles Bochet

VueJSにはルート要素が1つしか含まれないことを知っていたのに混乱しましたが、それでも同じ「テンプレート構文エラーコンポーネントテンプレートにはルート要素が1つだけ含まれる必要があります...」非常に単純なコンポーネントのエラー。 </ template>のスペルを誤って</ tempate>にしただけで、コピーして貼り付けたいくつかのファイルで同じエラーが発生していました。要約すると、コンポーネントのスペルに誤りがないか構文を確認してください。

0

コンポーネントテンプレートには、ルート要素を1つだけ含める必要があります。複数の要素でv-ifを使用している場合、代わりにv-else-ifを使用してそれらをチェーンします。

適切なアプローチは

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

間違ったアプローチ

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

マルチルートコンポーネント

その問題を回避する方法は、機能コンポーネントを使用することです。これらは、リアクティブデータを渡さないコンポーネントです。つまり、コンポーネントはデータの変更を監視せず、親コンポーネントの何かが変更されても自己更新しません。

これは回避策であるため、価格が伴います。機能コンポーネントにはライフサイクルフックが渡されません。インスタンスが少なくなり、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>

このようなことはできません。シングルルートコンポーネントの制限に違反します。

Solutionこのコンポーネントを機能的にし、レンダリングを使用する

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

0
Farwa Saddique