D
D
Dmitry Kuznetsov2021-02-16 08:19:25
Vue.js
Dmitry Kuznetsov, 2021-02-16 08:19:25

Why is the list not updating in vue template?

Hello. I can not solve the problem for about a week. I have a menu component that receives a list of menus, stores it in VUEX, and sends it to the next (child) component. That, in turn, filters and outputs through the array to the same component, but already recursively (through itself).
There is a button, by pressing which the array from vuex is iterated. And according to a certain condition, it should open or close the drop-down menu. The list itself changes, I already checked it, but in the template it does not change in any way. Tell me, please, where to dig.

PS: the code was specially shortened. Since the rest is not needed and just increases the number of lines.

Header (main component):

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



And itself, in fact, 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>



There is also the (action) toggleMenuItem method , which is found in Vuex. But it definitely works, so I see no point in posting it here.

I really hope for your decision. I can't do it right.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question