The v-for loop and key attribute usage

Couldn't make the title more relevant, sorry about that ....

  • I have a [] property in my data property that is populated with items with an external API call

  • I scroll [] with v-for

    in the main div in my template and fill page

  • there is a toggleable div in every main div which is hidden by default and is toggleable, show or not

here is the code

<template>

  <div>    
      // MAIN DIV
      <div v-for="(item, index) in myArray :key="index"> 
          //populate the elements using revelevant data
        <button @click="toggleDiv"">show/hide</button>

        //togglelable div
           <div v-if="displayDiv">
            //some data
        </div>
      </div>
  </div>
</template>

<script>
    export default{
        data(){
            return{
                myArray: [],
                displayDiv: false
            }
        },
        methods: {
            toggleDiv(){
                this.displayDiv = !this.displayDiv;
            }
        }

    }
</script> 

      

So my problem is

  • when i click on a button in a separate div to show the hidden div, all hidden divs of all other divs are shown as well.

  • How can I restrict this due to only the corresponding hidden div being toggled when the corresponding button of that div is clicked

  • should i use the attribute key

    to allow vue to differentiate the div or should i use any logic

+3


source to share


3 answers


The problem is that you have one true or false property to open all sections, displayDiv , its not for the element.

    data(){
        return{
            myArray: [],
            displayDiv: false
        }
    }

      

If you cannot modify the data elements of the array you receive at the remote location, you can simply pin the elements and add a property to each element after you receive it.



Like this:

// I'll assume your api looks somewhat like this

 return axios.get('apirequest')
.then(function (res) {

// Create a new list 
var listOfItemsWithAddedProp = [];

// Loop all the items of the response..
for(var item of res.data){

    // ..and add one or multiple props
    item.open = false;

    // Then push modified item to the new list
    listOfItemsWithAddedProp.push(item);
}

// Return or set the new list to your "myArray" in your example
return listOfItemsWithAddedProp;

      

})

+2


source


You must leave the key name and value like this, don't rename it.



<div v-for="(value, key, index) in Your-object">
  {{ index }}. {{ key }}: {{ value }}
</div>

      

+2


source


Create a new component for your separate Item and encapsulate the behavior of the shown item or not.

Main component:

<template>

    <div v-for="item in myArray"> 
     <item :item=item>
    </div>
    ...

</template>

<script>

    import Item from './Item.vue'
    ...
    export default{
      components: {
        Item
      }
    }

</script>

      

Component element:

<template>
  <div>
     <button @click="toggleDiv()"">show/hide</button>
     <div v-if="displayDiv">
      ...
     </div>
  </div>
</template>



 <script>
    export default{
        props: ['item']
        data(){
            return{
                displayDiv: false
            }
        },
        methods: {
            toggleDiv(){
               this.displayDiv = !this.displayDiv;
            }
        }
    }
 </script>

      

+1


source







All Articles