Reputation: 1962
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?
Upvotes: 1
Views: 2844
Reputation: 159
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>
Upvotes: 1
Reputation: 146
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
Upvotes: 1