为什么单击一个项目时,所有项目都会打开

why when click on an item, all item opens

我有一个带手风琴的列表,当你点击一个项目时,所有项目都会打开,我只需要打开一个, 我知道需要一个循环来遍历所有项目并将 class 应用于特定项目,但是如何做到这一点,请帮助
组件:

  <ul class="accordion accordion__trigger"
      :class="{'accordion__trigger_active': visible}"
      @click="open">
    <li class="accordion__item" v-for="category in MAIN_CATS">
        <nuxt-link exact no-prefetch active-class="link-active"
                   :to="`/category/${category.id}`"
                   class="menu-button">
          {{ category.title }}
        </nuxt-link>
        <div class="accordion__content">
          <div class="menu-sub-list" v-show="visible">
              <ul class="sub-list">
                <li class="menu-item"
                    v-for="sub in SUB_CATS(category.id)"
                    :key="sub.id">
                  <nuxt-link :to="`/category/${sub.id}`" class="menu-button">
                    {{ sub.title }}
                  </nuxt-link>
                </li>
              </ul>
          </div>
        </div>
    </li>
  </ul>

代码:

name: "acc",
  data() {
    return {
      index: null,
      Accordion: {
        count: 0,
        active: null
      }
    };
  },
  computed: {
    ...mapGetters([
      'MAIN_CATS',
      'SUB_CATS'
    ]),
    visible() {
      return this.index === this.Accordion.active;
    }
  },
  methods: {
    ...mapActions([
      'GET_CATEGORIES_LIST',
    ]),
    open() {
      if (this.visible) {
        this.Accordion.active = null;
      } else {
        this.Accordion.active = this.index;
      }
    },
    start(el) {
      el.style.height = el.scrollHeight + "px";
    },
    end(el) {
      el.style.height = "";
    }
  },
  created() {
    this.index = this.Accordion.count++;
  },
  mounted() {
    this.GET_CATEGORIES_LIST()
  },

我有一个带手风琴的列表,当你点击一个项目时,所有项目都会打开,我只需要打开一个, 我知道需要一个循环来遍历所有项目并将 class 应用于特定项目,但是如何执行此操作,请帮助

您的代码与您提到的 中的代码有很多不同之处。

您可以注意到 @clickv-for 在同一行。

这样做的主要原因是能够轻松访问循环中每个元素的 index


为了不让你过于复杂,我创建了一个基本的 use case scenario:

<template>
  <div id="accordion" class="accordion-container">
    <ul
      v-for="(category, index) in items"
      :key="index"
      class="accordion accordion__trigger"
      :class="{'accordion__trigger_active': visible===index}"
      @click="visible=index"
    >
      <li class="accordion__item">
        {{ category.title }}
        <div class="accordion__content">
          <div class="menu-sub-list" v-show="visible===index">
            <ul class="sub-list">
              <li class="menu-item">{{ category.sub }}</li>
            </ul>
          </div>
        </div>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "trial-page",
  data() {
    return {
      items: [
        {
          title: "Accordion 1",
          text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
          sub: "Pellentesque risus mi"
        },
        {
          title: "Accordion 2",
          text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
          sub: "Pellentesque risus mi"
        },
        {
          title: "Accordion 3",
          text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
          sub: "Pellentesque risus mi"
        }
      ],
      visible: null
    };
  }
};
</script>

<style>
.accordion__trigger_active {
  background-color: blue;
  color: white;
}
</style>

您可以看到,在这种情况下,我们的想法是使用分配给 visible 数据 属性 的 index 值进行操作。

我们只是检查visible是否等于当前按下的值为index的项目。

我们有条件地 v-show 元素并触发 class :class="{'accordion__trigger_active': visible===index}".


请注意,如果您在同一个组件中有更多 v-for 循环,那么您需要确保用于 visible 的值始终是唯一的,因为您可以简单地添加一些字符串到喜欢:

@click="visible=index+'category'"


另外记得在使用v-for时分配一个:key

示例: v-for="(category, index) in items" :key="index"