открытые сабменю по клику

172
09 мая 2022, 16:10

Есть две части меню, по клику на которые должно открываться соответствующее сабменю. У меня открываются оба сабменю. Как сделать их независимыми друг от друга?

<template>
<div class="nav-menu">
  <ul class="accordion" v-for="work of works" :key="${work}${work}">
    <li @click="isActive = !isActive">
      <div class="accordion__title" >{{work.name}}</div> 
        <ul :class="['accordion__submenu submenu', {'hidden' : !isActive}]">
      <li  class="submenu submenu__item" v-for="category in work.categories" :key="${category}${category}`">{{category}}

export default { name: 'NavMenu', data: () => ({ isActive: true, works: [ {name: 'archetecture', categories: ['interior', 'exterior', 'vr', 'animation']}, {name: 'not archetecture', categories: ['commrcial', 'video', '3D art']} ] }), } `
Answer 1

Я бы сделал так: В каждый объект массива works добавить свойство show:false

works: [ 
  {
    name: 'archetecture',
    show: false,
    categories: ['interior', 'exterior', 'vr', 'animation']
  }, 
  {
    name: 'not archetecture',
    show: false,
    categories: ['commrcial', 'video', '3D art']
  } 
] 

Цикл сделать не на <ul>, а на <li>. Так думаю будет логичнее

<li v-for="(work, index) of works" :key="index" @click="isActive(index)">

Ключ :key заменил на индекс, но это не принципиально, можете оставить свое значение. Событию @click передаем индекс элемента массива. И теперь остается только изменить в нужном элементе массива свойство show

methods: {
  isActive(index) {
    this.works.forEach(el => el.show = false);
    this.works[index].show = !this.works[index].show;
  }
}

И соответствующее подменю отображаем в зависимости от свойства show

<ul :class="['accordion__submenu submenu']" v-if="work.show">

Теперь каждое подменю работает независимо

Answer 2

Как вариант (на основании activeIndex - индекс активного элемента(объекта) в вашем входном массиве). При нажатии добавляете индекс элемента, на котором нажали в activeIndex и далее используете его значение, чтобы распределить кому отображаться, а кому и "скрыться":

new Vue({
  el: '#app',
  data: () => ({
    activeIndex: null,
    works: [{
      name: 'archetecture',
      categories: ['interior', 'exterior', 'vr', 'animation']
    }, {
      name: 'not archetecture',
      categories: ['commrcial', 'video', '3D art']
    }]
  }),
  methods: {
    openSubmenu(id) {
      this.activeIndex = this.activeIndex === id ? null : id
    }
  }
})
.hidden {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
  <div class="nav-menu">
    <ul class="accordion">
      <li @click="openSubmenu(index)"  v-for="(work, index) of works" :key="index">
        <div class="accordion__title">{{work.name}}</div>
        <ul :class="['accordion__submenu submenu', {'hidden' : index !== activeIndex}]">
          <li class="submenu submenu__item" v-for="category in work.categories" :key="category">{{category}}</li>
        </ul>
      </li>
    </ul>
  </div>
</div>

Вариант, где вместо индекса используется уникальный идентификатор (id) каждого отдельного пункта меню(если он есть конечно):

new Vue({
  el: '#app',
  data: () => ({
    activeId: null,
    works: [{
      id: 'uid1',
      name: 'archetecture',
      categories: ['interior', 'exterior', 'vr', 'animation']
    }, {
      id: 'uid2',
      name: 'not archetecture',
      categories: ['commrcial', 'video', '3D art']
    }]
  }),
  methods: {
    openSubmenu(id) {
      this.activeId = this.activeId === id ? null : id
    }
  }
})
.hidden {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
  <div class="nav-menu">
    <ul class="accordion">
      <li @click="openSubmenu(work.id)" v-for="(work, index) of works">
        <div class="accordion__title">{{work.name}}</div>
        <ul :class="['accordion__submenu submenu', {'hidden' : work.id !== activeId}]">
          <li class="submenu submenu__item" v-for="category in work.categories">{{category}}</li>
        </ul>
      </li>
    </ul>
  </div>
</div>

READ ALSO
Зона влияния города. Игра [дубликат]

Зона влияния города. Игра [дубликат]

Римейк вопроса, который участники, возмущенные отсутствием моих вариантов решение - закрыли

214
Неправильный вывод чисел

Неправильный вывод чисел

с помощью js нужно найти все натуральные числа из промежутка от 1 до 200, у которых количество делителей равно N, N вводим сами

177
Перевести js в php

Перевести js в php

Всем привет! У меня есть массив с объектами (data), также есть функция, которая выводить разметку и элементами из объектов внутри массиваМне...

302
Скрипт заблокирован политикой CORS

Скрипт заблокирован политикой CORS

В расширении для Chrome я пытаюсь загрузить некоторый скрипт с помощью XMLHttpRequest, но получаю следующую ошибку:

259