почему при нажатии на элемент открывается весь элемент - PullRequest
1 голос
/ 04 августа 2020

У меня есть список с аккордеоном, когда вы нажимаете на элемент, все элементы открываются, мне нужно открыть только один, я понимаю, что al oop необходим для перебора всех элементов и применения класса к определенному c один, а как это сделать, помогите пожалуйста компонент:

  <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()
  },

У меня есть список с гармошкой, когда вы нажимаете на элемент, все элементы открываются, мне нужно открыть только один, я понимаю, что al oop необходим для перебора всех элементов и применения класса к определенному c, но как это сделать, пожалуйста, помогите

1 Ответ

1 голос
/ 05 августа 2020

Есть несколько отличий между вашим кодом и кодом из ответа , на который вы ссылались.

Вы можете заметить, что @click находится в той же строке, что и v-for.

Основная причина этого заключается в том, чтобы иметь возможность легко получить доступ к index каждого элемента в al oop.

Чтобы не усложнять вам задачу, я создал базовый c сценарий использования :

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

Вы можете видеть, что идея состоит в том, чтобы работать со значением index, которое в данном случае присвоено свойству visible data.

Мы просто проверяем, совпадает ли visible с текущим нажатием элемент со значением index.

С этим мы условно v-show элемент и запускаем класс :class="{'accordion__trigger_active': visible===index}".

Обратите внимание: если у вас было больше v-for циклов в одном компоненте, вам нужно было бы убедиться, что значение, используемое для visible, всегда уникально, для этого вы можете просто добавить к нему строку, например:

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

Также не забудьте присвоить :key при использовании v-for.

Пример: v-for="(category, index) in items" :key="index"

...