简体   繁体   中英

Toggle value from parent to child component in vuejs for hide/display with v-show in v-for loop

I'm trying to show or hide a list of items in a v-for.

Initially, I had everything in one component and when I clicked on the button to open, it opened up all the elements of my loop:

<template>
  <div v-for='item in items'>
    <button @click="isExpanded = !isExpanded">Toggle specific element</button>
    <ul v-show="isExpanded">
      <li v-for'subitem in item.subitems'>Sub items</li>
    </ul>
  </div>
</template>

<script>
  export default {
    data() {
      return: {
        isExpanded: false
      };
    },
  };
</script>

I want only one item to be opened by clicking.

I finally decided to put my ul list in a separate component .

<template>
  <div v-for='item in items'>
    <button @click="??">Toggle specific element</button>
    <MyListComponent :items="item.subitems"/>
  </div>
</template>

  <script>
  import MyListComponent from '…'
   export default {
     data() {
        return: {
            isExpanded: false
        }
     },

     components: { MyListComponent }
   }
  </script>

MyListComponent:

<template>
<ul v-show="isExpanded">
  <li v-for'item in items'>Sub items</li>
</ul>
</template>

<script>
export default {
     data() {
        return: {
            isExpanded: false
        }
     },

     props: ['items']

     methods: {
        toggle() {
          this.isExpanded = !isExpanded;
        }
     }
</script>

But I can't get the click of the parent button to change the "isExpanded" value in the child component.

Can you tell me how to do it?

As Delena Malan says, you can use props. But you need to have one "isExpanded" variable for each items displayed. So my advice is to store it in your items array. So each item has its own isExpanded boolean.

<div v-for="(item, index) of items" :key="index">
  <button @click="item.isExpanded = !item.isExpanded">Toggle specific element</button>
  <Item :subItems="item.subItems" :isExpanded="item.isExpanded"/>
</div>

I did it my way on this Codesandbox

Remove all isExpanded implementation in child list. Handle it in the parent and send it to the child.

<template>
  <div v-for='item in items'>
    <button @click="ToggleIsExpanded">Toggle specific element</button>
    <MyListComponent :items="item.subitems"/>
  </div>
</template>

  <script>
  import MyListComponent from '…'
   export default {
     data() {
        return: {
            isExpanded: false
        }
     },

     components: { MyListComponent },
     methods: {
       ToggleIsExpanded: function() {
         this.isExpanded = !this.isExpanded
       }
     }
   }
  </script>

MyListComponent:

<template>
<ul v-show="isExpanded">
  <li v-for'item in items'>Sub items</li>
</ul>
</template>

<script>
export default {
     props: ['items', 'isExpanded']
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM