0

It's incredible! I have already used nested components in Vue.js and they worked. Now, I created two more and they didn't work. I just can't see the problem.

obs. I will include only the two components that can't be nested.

App.vue

<template>

    <div id="app">
        <menu-home-component></menu-home-component>  Here the component works but I want it in another component.

    ...
</template>

<script>

import MenuHomeComponent from './components/MenuHomeComponent'
import ImoveisDestaqueComponent from './components/ImoveisDestaqueComponent'
 import PainelAnuncios from './components/PainelAnuncios'


var data = {
    secao : "mensagens"
}

export default {
    name: 'app',
    components : {
        MenuHomeComponent, ImoveisDestaqueComponent, PainelAnuncios
    },
    data : function() { return data }
}
</script>

This is the HomeComponent which contains the MenuHomeComponent. I can't use MenuHomeComponent , "Unknown custom element" error.

<template>
    <div>
        <menu-home-component></menu-home-component>  "Unknown custom element here" error
    </div>
</template>

<script>

    import MenuHomeComponent from './MenuHomeComponent'
    import ImoveisDestaqueComponent from './ImoveisDestaqueComponent'

    export default {
    name: "home"

    }

</script>

MenuHomeComponent contains just a placeholder text:

<template>

    <div>
        Menu Home.
    </div>

</template>

<script>

    export default {        
    }

</script>

Updated to show a working scenario

This is the PainelAnuncios.vue Component

  <script>


import ListaAnuncios from './ListaAnuncios';
import FetchData from 'vue-fetch-data';
import axios from 'axios';



export default {
    name : "painelanuncios"
        ,
    data: function() {
    return {anuncios: [], erroConexao : false}
    },

     mounted () 
{

axios.get('http://www.example.com/anuncios2').then(response => {  this.anuncios = response.data;  }).catch( error => { this.erroConexao = true } );




},
    methods: {

       suspenderAnuncio: function(event)
       {
             alert("depois de alterado, ativo" + event.ativo);

          axios.post('http://www.example.com/painel_de_controle/suspender_anuncio', { imovel_id : event.imovelId, tipo_imovel : 'casa', tipo_anuncio : 'venda', ativo : event.ativo  }).then(response => {  this.anuncios = response.data;  }).catch( error => { alert("não foi possível atualizar o anúncio!") } );
       }


    }

}

</script>

<template>

<div>

<div v-if="erroConexao">
<div class="alert alert-danger alert-dismissible fade show" role="alert">
  <strong>Erro ao conectar!</strong> Por favor, verifique sua conexão com a internet.
  <button type="button" class="close" data-dismiss="alert" aria-label="Close">
    <span aria-hidden="true">&times;</span>
  </button>
</div>
</div>

<lista-anuncios v-on:onSuspenderAnuncio="suspenderAnuncio" v-bind:anuncios="anuncios" ></lista-anuncios>
</div>

</template>

This is the ListaAnuncios.vue component

<script>

import Anuncio from './Anuncio';

export default {
    name: "listaanuncios",


    estaAberto : false,
    props: ['anuncios', 'comunicacao'],

    methods: {

       suspenderAnuncio: function(event)
       {
          this.$emit('onSuspenderAnuncio', event);
       },
       testar : function(event)
       {
            alert("lieta testar");
       }


    }

}


</script>

<template>

<div>
<div>{{ comunicacao }}</div>
<div v-for="anuncio in anuncios" > 
<anuncio v-model="comunicacao" v-on:onTestar="testar" v-on:onSuspenderAnuncio="suspenderAnuncio" v-bind:anuncio="anuncio"></anuncio>
</div>
</div>

</template>


<style>
</style>

This is the Anuncio Component

     <script>

  export default {
        name: 'anuncio',
        data : function() {
        return {  estaAberto: false, url : 'http://www.example.com' }
        },
        methods: {
             abrirMensagem : function() {
               this.estaAberto = !this.estaAberto;
             },

               testar(event) {

                this.$emit("onTestar", 'event');

               },

              suspenderAnuncio : function(event)
             {

                 var ativo = parseInt(this.anuncio.Ativo);


                   alert("valor do ativo" + ativo);

                   if(ativo == 1)
                   {
                       ativo = 0;
                   }
                   else
                   {
                    ativo = 1;
                   }

                 this.anuncio.ativo = ativo;

                  this.$emit('onSuspenderAnuncio', { imovelId : this.anuncio.ImovelId, ativo : ativo });
             },
             mudarComunicacao : function(event) {
                    this.$emit("input", event.target.value)
             }

        }
        ,

            props : ["anuncio", "value"] 

  }

</script>

<template>

<div>


<input v-on:input="mudarComunicacao" />
<div></div> <img  v-on:click="testar" v-bind:src=" this.url + anuncio.Imagem" /><div> <div> <span> <a v-bind:href="this.url + '/' + anuncio.TipoImovel + 's/' + anuncio.ImovelId ">visualizar</a> </span> <span> <a v-bind:href="this.url + '/' + anuncio.TipoImovel + 's/' + anuncio.ImovelId + '/edit' ">editar</a> </span> 
<span><span v-on:click="suspenderAnuncio">suspender</span></span>

 </div>  </div>
</div>

</template>    
<style scoped>
</style>
5
  • So are you saying you have two template and script element blocks in your App.vue component fiile? I'm not sure you can do that. Commented Dec 15, 2017 at 14:22
  • Yup. That is not possible. 1 component per file. Anything out side that is asking for trouble Commented Dec 15, 2017 at 14:23
  • No, one in each file. Commented Dec 15, 2017 at 14:25
  • With the solution of @SciGuyMcQ the error vanished. I updated my question and included components that can be used in another component without a "components" declaration on the parent. Can someone explain why? Commented Dec 15, 2017 at 16:31
  • One more thing. I am using vue routes. Commented Dec 15, 2017 at 16:50

1 Answer 1

3

In the second exported object (the second script element that I assume is in another file other than App.vue, or maybe you are saying that is the version that will not work) there is no components definition. You need a components object member to register the nested component MenuHomeComponent like this.

<script>
    import MenuHomeComponent from './MenuHomeComponent'
    export default {
       components: { MenuHomeComponent }
    }
</script>
Sign up to request clarification or add additional context in comments.

4 Comments

I don't think I need to do this. Besides I used other components EXACTLY the way I posted in this question I they didn't throw errors.
I would suggest a read through of the docs vuejs.org/v2/guide/single-file-components.html
Could you please try to do it? I am fairly confident that @SciGuyMcQ is correct.
It worked, but... can you explain why the components that I included in the update of my question work: I updated the first code block (App.vue) , you can see that it imports a PainelAnuncios component. In the components below through the chain I never used the components declaration and it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.