Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Erro após Aula 06 - 06

A mensagem que estou visualizando no console é a seguinte, logo após digitar npm run dev na pasta alurapic:

ERROR in ./node_modules/vue-loader/lib/template-compiler?{"id":"data-v-74b1de62","hasScoped":false,"buble":{"transforms":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/components/home/Home.vue
(Emitted value instead of an instance of Error)
  Error compiling template:


    <h1 class="centralizado">Alurapic</h1>

  <input type="search" class="filtro" @input="filtro = $event.target.value" placeholder="filtrem por parte do titulo">

   <ul class="lista-fotos">
      <li class="lista-fotos-item" v-for="foto of fotosComFiltro">
        <meu-painel :titulo="foto.titulo">
              <imagem-responsiva :url="foto.url" :titulo="foto.titulo"/>
        </meu-painel>
      </li>
   </ul>


  - Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.

 @ ./src/components/home/Home.vue 11:0-251
 @ ./src/routes.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8081 webpack/hot/dev-server ./src/main.js

E aqui está o arquivo Home.vue


<template>

      <h1 class="centralizado">Alurapic</h1>     

    <input type="search" class="filtro" @input="filtro = $event.target.value" placeholder="filtrem por parte do titulo">

     <ul class="lista-fotos">
        <li class="lista-fotos-item" v-for="foto of fotosComFiltro">
          <meu-painel :titulo="foto.titulo">
                <imagem-responsiva :url="foto.url" :titulo="foto.titulo"/>
          </meu-painel>                       
        </li>
     </ul>

</template>

<script>
  import Painel from '../shared/painel/Painel.vue';//import Painel -> o Painel é o nome que é adicionado a partir do arquivo de nome Painel
  import ImagemResponsiva from '../shared/imagem-responsiva/ImagemResponsiva.vue';

  export default {

    components:{
      'meu-painel': Painel,
      'imagem-responsiva': ImagemResponsiva
    },

    data(){
      return{
        titulo: 'Alurapic',
        fotos:[],
        filtro: ''
      }
    },

    computed:{
      fotosComFiltro(){
        if(this.filtro){
          /*filtrar*/
         let exp = new RegExp(this.filtro.trim(), 'i');
         return this.fotos.filter(foto=> exp.test(foto.titulo));
        }else{
          return this.fotos;
        }
      }
    },

    created(){

      let promise = this.$http.get('http://localhost:3000/v1/fotos')
      .then(res => res.json())
      .then(fotos => this.fotos = fotos, err => console.log(err));

    }
  }
</script>

<style>

.centralizado{
  text-align: center;
}

.lista-foto{
  list-style: none;
}

.lista-fotos .lista-fotos-item{
  display: inline-block;
}


.filtro{
  display: block;
  width: 100%;
  padding: 10px;
}

</style>

Não consigo localizar o erro. Já reiniciei os terminais e nada

1 resposta
solução!

Fala ai Jorge, tudo bem? O problema está no template do seu componente, vamos olhar a mensagem de erro:

Component template should contain exactly one root element

Repare que o Vue está dizendo que seu componente deve ter apenas um root, se a gente olhar o template dele:

<template>
      <h1 class="centralizado">Alurapic</h1>     

    <input type="search" class="filtro" @input="filtro = $event.target.value" placeholder="filtrem por parte do titulo">

     <ul class="lista-fotos">
        <li class="lista-fotos-item" v-for="foto of fotosComFiltro">
          <meu-painel :titulo="foto.titulo">
                <imagem-responsiva :url="foto.url" :titulo="foto.titulo"/>
          </meu-painel>                       
        </li>
     </ul>
</template>

O template contém três elementos root, nesse caso, o ideal seria criar uma div para encapsular os três:

<template>
  <div>
      <h1 class="centralizado">Alurapic</h1>     

    <input type="search" class="filtro" @input="filtro = $event.target.value" placeholder="filtrem por parte do titulo">

     <ul class="lista-fotos">
        <li class="lista-fotos-item" v-for="foto of fotosComFiltro">
          <meu-painel :titulo="foto.titulo">
                <imagem-responsiva :url="foto.url" :titulo="foto.titulo"/>
          </meu-painel>                       
        </li>
     </ul>
  </div>
</template>

Assim o template agora possui apenas um root.

Mas porque ele não pode retornar mais de um elemento root? Isso é um pouco mais complexo, mas, basicamente seu template dentro de um arquivo .vue no final irá resultar em várias funções JavaScript.

E essas funções vão formar uma cadeia, onde, é necessário apenas uma função como ponto de partida (que seria o root) e seus filhos iriam preencher a cadeia.

Espero ter ajudado.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software