@click внутри v — для запуска всех событий @click

#javascript #vue.js #nuxt.js

#javascript #vue.js #nuxt.js

Вопрос:

При @click запуске одного из v-for них свойство отображения во всех объектах в массиве обновляется, а не только по индексу. Я хочу, чтобы только тот элемент, который является щелчком, получал событие и обновлял свойство отображения, а не все из них.

 <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>
  

Ответ №1:

Проблема заключается в коде, который объединяет все элементы массива с одним и тем же объектом, который является наблюдаемым, следовательно, изменение свойства будет применено ко всем элементам массива как . const status = Array(data.trainingModules.length).fill({ display: false }) display status[0] === status[1]

Вместо этого используйте map, и он будет работать так, как ожидалось:

const status = data.trainingModules.map(() => ({ display: false }));