Привет. Не могу решить проблему уже около недели. Есть компонент меню, который получает список меню, сохраняет во VUEX и отправляет в следующий (дочерний) компонент. Тот в свою очередь фильтрует и выводит через массив в этот же компонент, но уже рекурсивно (через сам себя).
Есть кнопка, по нажатию которой происходит перебор массива из vuex. И по определённому условию должен открывать или закрывать выпадающее меню. Сам список меняется, уже проверил, но в шаблоне он ни как не меняется. Подскажите, пожалуйста, куда копать.
PS: код специально сократил. Так как остальное не нужно и просто увеличивает количество строк.
Header (главный компонент):
Header<template>
<header>
<left-menu :active="leftMenuStatus"></left-menu>
</header>
</template>
<script>
import { mapState, mapActions } from "vuex"
export default {
name: "v-header",
props: {
icons: {
type: Array,
default: null
},
items: {
type: Array,
default: null
},
},
created() {
this.loadMenus // Делаем запрос на сайт и от туда получаем меню. Выполняется через vuex
},
computed: {
...mapActions({
loadMenus: 'loadMenus',
})
},
}
</script>
Компонент left-menu:
left-menu
<template>
<div id="slide-out" class="side-nav fixed">
<ul class="custom-scrollbar">
<li class="scroll">
<VuePerfectScrollbar class="scroll-area" :settings="settings">
<ul id="scrollable" class="collapsible collapsible-accordion">
<div v-for="menu in filteredMenu()" :key="menu.id">
<left-menu-item :menu="menu"></left-menu-item>
</div>
</ul>
</VuePerfectScrollbar>
</li>
</ul>
<hr>
<div class="sidenav-bg mask-strong"></div>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
import VuePerfectScrollbar from 'vue-perfect-scrollbar'
export default {
name: "left-menu",
components: {
VuePerfectScrollbar
},
props: {
active: {
type: Boolean,
default: false
}
},
data() {
return {
settings: {
maxScrollbarLength: 100
},
}
},
computed: {
...mapGetters({
leftMenus: 'getLeftMenus'
})
},
methods: {
filteredMenu() {
return this.leftMenus.filter((item) => item.parent_id == null)
},
},
}
</script>
И сам, собственно,
left-menu-item:
left-menu-item
<template>
<div>
<li v-if="filteredSubMenu().length > 0">
<a :href="menu.url" class="collapsible-header-list">
<i :class="getIcon(menu)"></i>
{{ menu.name }}
</a>
<a class="collapsible-header waves-effect arrow-r collapsible-open-list"
:class="{ 'active': menu.toggle }"
@click="menuItemCollapsible(menu.id);">
<i class="fas fa-angle-down rotate-icon"></i>
</a>
<div v-if="menu.toggle" class="collapsible-body d-block">
<ul class="collapsible collapsible-accordion">
<div v-for="menu in filteredSubMenu()" :key="menu.id">
<left-menu-item :menu="menu" :step="stepsPlus()"></left-menu-item>
</div>
</ul>
</div>
</li>
<li v-else>
<a v-if="menu.url != '#'" :href="menu.url" class="collapsible-header waves-effect arrow-r">
<i :class="getIcon(menu)"></i> {{ menu.name }}</a>
</li>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
name: "left-menu-item",
props: {
menu: {
type: Object,
default: {}
},
step: {
type: Number,
default: 0
},
},
computed: {
...mapGetters({
leftMenus: 'getLeftMenus',
}),
},
data() {
return {
steps: this.step,
}
},
created() {
this.stepsPlus()
},
methods: {
menuItemCollapsible(id){
this.$store.dispatch('toggleMenuItem', id)
},
filteredSubMenu() {
return this.leftMenus.filter(item => item.parent_id === this.menu.id)
},
stepsPlus(){
return this.steps + 1
},
getIcon(menuItem){
let faIcon = ''
// ...
return faIcon
}
},
},
}
</script>
Есть ещё метод (action)
toggleMenuItem, который находится во Vuex. Но он точно работает, так что выкладывать его здесь не вижу смысла.
Очень надеюсь на ваше решение. Не могу ни как сделать правильно.