Reputation: 6899
When a single @click
is triggered from within the v-for
the display property in all of the objects within the array is updated, rather than just by index. I only want that element that is click to receive the event and update the display property, not all of them.
<script>
import TransitionExpand from '@/transitions/transition-expand'
import ResourceCard from '@/components/resource-card'
export default {
components: {
TransitionExpand,
ResourceCard
},
data () {
return {
}
},
methods: {
toggle (evt, i) {
this.status[i].display = !this.status[i].display
}
},
async asyncData ({ app }) {
const { data } = await app.$axios.get('training_modules')
const status = Array(data.trainingModules.length).fill({ display: false })
return {
modules: data.trainingModules,
status
}
}
}
</script>
<template>
<div>
<div class="container px-4 mx-auto mt-16 lg:mt-32">
<div class="flex flex-wrap mb-20">
<h1 class="w-full lg:w-1/2 mb-6">Training Modules</h1>
<p class="w-full lg:w-1/2 leading-7 text-abbey"></p>
</div>
<div
v-for="(item, i) in modules"
:key="item.id"
class="mb-12"
>
<div class="flex items-center">
<h2>{{ item.title }}</h2>
<img @click="toggle($event, i)" class="ml-auto cursor-pointer" src="@/assets/images/icons/plus.svg" alt="open">
</div>
<TransitionExpand v-show="status[i].display">
<div class="">
<p class="mt-6 mb-12">{{ item.description }}</p>
<div class="flex flex-wrap -m-3">
<ResourceCard
v-for="resource in item.resources"
:key="resource.id"
:resource="resource"
/>
</div>
</div>
</TransitionExpand>
</div>
</div>
<BaseFooter />
</div>
</template>
Upvotes: 1
Views: 161
Reputation: 26075
Problem is in const status = Array(data.trainingModules.length).fill({ display: false })
code which is filing all array items with the same object which is observable hence change in display
property will be applied to all elements in the array as status[0] === status[1]
.
Use map instead and it will work as expected:
const status = data.trainingModules.map(() => ({ display: false }));
Upvotes: 1