如何在 Nuxt.js 中的 v-for 循环中使用按钮?

How use a button in v-for loop in Nuxt.js?

我在循环中使用 vuetify 的卡片组件来显示数据,但是当我单击卡片中存在的按钮时,循环中存在的所有卡片的所有按钮都会打开。我怎样才能只打开我单击的卡片按钮?

这是我的模板:

<template>
  <v-row>
    <v-col
      v-for="(prop, i) in Object.keys(linkIdeal)"
      :key="i"
      cols="6"
      lg="2"
      md="3"
      sm="4"
      class="mb-6"
      @click="console.log(prop)"
    >
      <v-card
        v-if="linkIdeal[prop].plant_associated[0].category == '1'"
        style="z-index: 0"
        :class="`mx-auto my-12 plant-card Vegetables`"
        width="100%"
      >
        <v-img
          :src="`${linkIdeal[prop].plant_associated[0].image}`"
          width="100%"
          height="200"
        ></v-img>
        <v-card-title class="white--text card-title justify-center">
          {{ linkIdeal[prop].plant_associated[0].name }}
        </v-card-title>
        <v-card-actions @click="show = !show" style="cursor: pointer">
          <span class="white--text btnDescr">Description</span>
          <v-spacer></v-spacer>
          <v-btn icon>
            <v-icon class="white--text">
              {{ show ? 'mdi-chevron-up' : 'mdi-chevron-down' }}
            </v-icon>
          </v-btn>
        </v-card-actions>
        <v-expand-transition>
          <div v-show="show">
            <v-divider></v-divider>
            <v-card-text>
              <span
                class="white--text"
                v-html="linkIdeal[prop].description"
              ></span>
            </v-card-text>
          </div>
        </v-expand-transition>
      </v-card>
    </v-col>
  </v-row>
</template>

这是我的脚本:

import {
  mapGetters
} from "vuex";
export default {
  props: {},
  data: () => ({
    linkIdeal: [],
    show: false,
  }),
  computed: {
    console: () => console,
    ...mapGetters({
      plantActive: 'permatheque/getPlant',
    }),
  },
  methods: {
    async getAssociatedPlant() {
      this.$axios.$get('...')
        .then(response => {
          //this.$store.commit('permatheque/setPlantAssociations', response)
          this.linkIdeal = response
          console.log(this.linkIdeal)
        }).catch(error => {
          console.log(error)
        });
    },
  },
  mounted() {
    this.getAssociatedPlant()
  }
}

感谢您的回答

您正在使用 1 show 变量作为所有卡片的状态,它们的 open/close 状态都取决于此,因此当您切换此状态时,所有卡片都会相应地操作。

如果你想为每张卡片设置一个 open/close 状态,那么你应该将它添加到每张卡片中(比如在它们自己的组件中)或者你可以跟踪打开的卡片(例如通过 ID)数组。两者都可以解决您的问题。 (片段来演示)

OPEN/CLOSE 数组中跟踪的状态

Vue.component('ToggleCard', {
  props: ['id', 'label', 'open'],
  methods: {
    onClick() {
      this.$emit("update:open")
    }
  },
  template: `
    <div
      class="cursor-pointer"
      :class="{
        open: open
      }"
      @click="onClick"
    >
      {{ label }} - {{ open }}
    </div>
  `
})

new Vue({
  el: "#app",
  data() {
    return {
      openedCards: [],
      cards: [{
          id: 0,
          label: "CARD 1",
        },
        {
          id: 1,
          label: "CARD 2",
        },
        {
          id: 2,
          label: "CARD 3",
        },
      ]
    }
  },
  methods: {
    isOpen(id) {
      return this.openedCards.includes(id)
    },
    updateOpenedCards(id) {
      if (this.isOpen(id)) {
        this.openedCards = this.openedCards.filter(cardId => cardId !== id)
      } else {
        this.openedCards = [...this.openedCards, id]
      }
    }
  },
  template: `
    <div>
      <toggle-card
        v-for="card in cards"
        :key="card.id"
        :id="card.id"
        :label="card.label"
        :open="isOpen(card.id)"
        @update:open="() => updateOpenedCards(card.id)"
      ></toggle-card>
    </div>
  `
})
.cursor-pointer {
  cursor: pointer;
}

.open {
  background: green;
  color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

OPEN/CLOSE 在单独的组件中跟踪状态

Vue.component('ToggleCard', {
  props: ['id', 'label'],
  data() {
    return {
      open: false,
    }
  },
  template: `
    <div
      class="cursor-pointer"
      :class="{
        open: open
      }"
      @click="open = !open"
    >
      {{ label }} - {{ open }}
    </div>
  `
})

new Vue({
  el: "#app",
  data() {
    return {
      cards: [{
          id: 0,
          label: "CARD 1",
        },
        {
          id: 1,
          label: "CARD 2",
        },
        {
          id: 2,
          label: "CARD 3",
        },
      ]
    }
  },
  template: `
    <div>
      <toggle-card
        v-for="card in cards"
        :key="card.id"
        :id="card.id"
        :label="card.label"
      ></toggle-card>
    </div>
  `
})
.cursor-pointer {
  cursor: pointer;
}

.open {
  background: green;
  color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>