Attribute v-on:click n works when set in vuejs 3

Asked

Viewed 41 times

1

I’m getting a json with a collection of objs, the quantity is dynamic, I’m creating the div element and added a dynamic id to it, my idea was to make div.setAttribute("onclick", alert("${idRotativo}")) but Vue does not find the function alert when I do so,

I also made :

div.setAttribute("@click", alerta("${idRotativo}")) but of that mistake:

inserir a descrição da imagem aqui

With: div.setAttribute("v-on:click", alerta("${idRotativo}"))

No error and it can set the attribute "v-on:click", but does not work. inserir a descrição da imagem aqui

I made an ex of what I need in jsFiddle When you click on the row it returns the id of the clicked element, https://jsfiddle.net/CarlosAlexandreleutz/a89m4r7d/6/

I thought it might be like I was creating the html element that is printed on the screen

then tried with Document.createelement('div');

var conter = 0;
            function verificaRelacionamento (element){
                conter++
                let elemento = element;
                let div = document.createElement('div');
                div.textContent = `Id: ${elemento.id} Descrição: ${elemento.descricao} Descrição do pai ${elemento.descricaoPai}`;
                let idRotativo = 'teste' + conter;
                div.setAttribute("id", idRotativo)
                div.setAttribute("v-on:click", `alerta("${idRotativo}")`)
                let paiDeTodo = document.getElementById('paiDeTodos');
                paiDeTodo.appendChild(div)                                             
            }
            function tamanhoDoArray(a){
                let array = a;
                array.forEach(verificaRelacionamento)
            }
            function alerta(a){
                alert(a)
            }

And with a string template:

     var conter = 0;
                var html = '';
               function verificaRelacionamento(element) {
                    conter++
                    let elemento = element;
                    html += `<div v-on:click="alerta('colapser-${conter}')" class="colapser-${conter}">
                    Id: ${elemento.id} Descrição: ${elemento.descricao} Descrição do pai ${elemento.descricaoPai}
                    <button v-on:click="alerta('colapser-${conter}')">teste</button>
                    </div>`;
                    document.getElementById("paiDeTodos").innerHTML = html;
                    
                } 
           
            function tamanhoDoArray(a){
                let array = a;
                array.forEach(verificaRelacionamento)
            }
            function alerta(a){
                alert(a)
            }

the 2 generate the same html, but nothing happens when I click on them

my final goal and make an account plan, I will use this id to add and remove a class to collapse the items, msm the way it has in the google inspection, that the user can click the arrow and go seeing what is inside the elements, inserir a descrição da imagem aqui

NOTE: if I copy the generated element in the browser and paste it into html, it works

1 answer

0


First you can create a component that collapses, and call this component in your vew.

Then you can use 'v-for' which is a Vue.js directive to make a loop, this loop must receive the json information.

This loop will render your component that has the collapser as many times as needed, or as many times as your v-for variable has to traverse from your json.

If you use JSON.parse(Response) passing the server response as parameter it will separate the objs array into several separator objs that v-for can go through.

Ai you can continue and pass the values you are receiving in json as parameter to your collapser or print them inside your component with {{items.value}} for ex.

If you are sending by parameter you need to prepare the component to receive this data.

You can create the variables in the component and pass in its component like this:

But for you n to send a string to variable id you have to use:

v-bind:id="items.id"

So Vue will intender that it is not a string that you will pass to variable id that you created there in your component by ex.

And in your component remember to create a default value for your variable, to avoid error if the expected field has to be rendered, but n has received a value

for ex:

 

  

 props:{ 

        id:{ type: String, default: 'vazio' }, 

       }, 

  

But for this to work you have to force the component to be loaded only after the request is completed, this is because of how Vue renders the page

For this you can use Suspense which is a special component that renders fallback content instead of your component until a condition is met, available in Vue.js 3 and a v-if="" to see if the variable with the server reset is filled

getting something like

 

  

 <Suspense> 

                 <template #default> 

                    <div v-if="items != undefined"> 

                        <colapser v-for="itens in items" :key="itens.id" v-bind:id="itens.hierarquia" v-bind:descricao="itens.descricao"  ></colapser> 

                    </div> 

                 </template> 

                 <template #fallback> 

                     caregando... 

                 </template> 

            </Suspense> 

  

:

 

  

import colapser from "Seu componente colapser" 

import { ref, onMounted } from "vue"; 

export default { 

    components: { colapser }, 

    setup() {     

        var items = ref(null); 

        onMounted(async () =>{ 

            const funçãoQueVaiBuscarOJson = async() => { 

                //Aqui sua requisição 

                return resp; 

            }; 

            items.value = await funçãoQueVaiBuscarOJson();   

            // aqui você atribui a variável item a resposta do servido    

        }); 

        return { 

            items //essa é a variável que o v-for vai percorre 

        } 

    } 

} 

  

and the component can stay like this:

 

  

export default { 

     

    props:{ 

        id:{ type: String, default: 'vazio' }, 

     

    }, 

    data(){ 

        return{ 

            isOpen: false,             

        } 

    }, 

    methods:{ 

        toggle(){ 

            this.isOpen = !this.isOpen 

        }             

    }, 

     setup() {  

        function mainNavToggle(a) { 

            var mainNav = document.getElementById(a); 

            mainNav.classList.toggle('collapsed'); 

        } 

        return{ 

             mainNavToggle 

  

        } 

     }     

} 

  
 

  

<template> 

    <div v-show="isOpen" id="mainNav" > 

          <div> {{id}}</div> 

     </div>           

         

</template> 

  

With the toggle method it will already open and close the collapsers without interfering with the other components because I used @click.stop.Prevent="toggle"

Browser other questions tagged

You are not signed in. Login or sign up in order to post.