Vue:如何为动态生成的菜单中的每个条目切换“打开”类

时间:2019-04-04 10:16:32

标签: vue.js menu dynamically-generated

我有一个菜单,该菜单是从包含菜单项的给定对象动态生成的。菜单分为三个级别。为了打开子菜单(和子子菜单),我必须相应地为open元素切换类li。我正在努力弄清其背后的逻辑。

菜单对象:

menu: [
    {
      id: '1',
      category: 'Home',
      items: [
        {
          id: '1.1',
          name: 'Dashboard',
          icon: 'home',
          target: 'home'
        },
        {
          id: '1.2',
          name: 'About',
          icon: 'info-circle',
          target: 'about'
        }
      ]
    },
    {
      id: '2',
      category: 'Help',
      items: [
        {
          id: '2.1',
          name: '1st Lvl Entry 1',
          icon: 'home',
          items: [
            {
              id: '2.1.1',
              name: '2nd Lvl Entry 1',
              icon: 'info-circle',
              target: 'about'
            },
            {
              id: '2.1.2',
              name: '2nd Lvl Entry 2',
              icon: 'home',
              items: [
                {
                  id: '2.1.2.1',
                  name: '3nd Lvl Entry 1',
                  icon: 'home',
                  target: 'home'
                },
                {
                  id: '2.1.2.2',
                  name: '3nd Lvl Entry 2',
                  icon: 'info-circle',
                  target: 'about'
                }
              ]
            },
            {
              id: '2.1.3',
              name: '2nd Lvl Entry 3',
              icon: 'home',
              items: [
                {
                  id: '2.1.3.1',
                  name: '3nd Lvl Entry 3',
                  icon: 'info-circle',
                  target: 'about'
                },
                {
                  id: '2.1.3.2',
                  name: '3nd Lvl Entry 4',
                  icon: 'home',
                  target: 'home'
                }
              ]
            }
          ]
        },
        {
          id: '2.2',
          name: '1st Lvl Entry 2',
          icon: 'home',
          target: 'home'
        }
      ]
    }
  ]

菜单组件:

<template>
  <div class="bg-white">
    <div class="content">
      <!-- Toggle Main Navigation (mobile only) -->
      <div class="d-lg-none push">
        <button
          type="button"
          @click="hideMobileNav = !hideMobileNav"
          class="btn btn-block btn-light d-flex justify-content-between align-items-center"
        >
          Menu
          <font-awesome-icon icon="bars" />
        </button>
      </div>
      <!-- END Toggle Main Navigation -->

      <!-- Main Navigation -->
      <div
        id="main-navigation"
        class="d-lg-block push"
        :class="{ 'd-none': hideMobileNav }"
      >
        <first-level :items="menu" />
      </div>
      <!-- END Main Navigation -->
    </div>
  </div>
</template>

<script>
import firstLevel from './firstLevel'

export default {
  name: 'mainNav',
  components: {
    firstLevel
  },
  data() {
    return {
      hideMobileNav: true
      menu: [] // see menu snippet above
    }
  }
}
</script>

一级组件:

<template>
  <ul class="nav-main nav-main-horizontal nav-main-hover">
    <template v-for="firstLevel in items">
      <li
        :key="firstLevel.category"
        v-text="firstLevel.category"
        class="nav-main-heading"
      ></li>
      <li
        v-for="item in firstLevel.items"
        :key="item.id"
        class="nav-main-item"
        :class="{ open: item.isOpen }"
      >
        <router-link
          :to="{ name: item.target }"
          class="nav-main-link"
          :class="{ 'nav-main-link-submenu': item.items }"
        >
          <font-awesome-icon
            :icon="item.icon"
            fixed-width
            class="nav-main-link-icon"
          />
          <span v-text="item.name" class="nav-main-link-name"></span>
        </router-link>
        <template v-if="item.items">
          <second-level :items="item.items" />
        </template>
      </li>
    </template>
  </ul>
</template>

<script>
import secondLevel from './secondLevel'
export default {
  name: 'firstLevel',
  props: ['items'],
  components: {
    secondLevel
  }
}
</script>

第二级组件:

<template>
  <ul class="nav-main-submenu">
    <li
      v-for="item in items"
      :key="item.id"
      class="nav-main-item"
    >
      <router-link
        :to="{ name: item.target }"
        class="nav-main-link"
        :class="{ 'nav-main-link-submenu': item.items }"
      >
        <font-awesome-icon
          :icon="item.icon"
          fixed-width
          class="nav-main-link-icon"
        />
        <span v-text="item.name" class="nav-main-link-name"></span>
      </router-link>
      <template v-if="item.items">
        <third-level :items="item.items" />
      </template>
    </li>
  </ul>
</template>

<script>
import thirdLevel from './thirdLevel'

export default {
  name: 'secondLevel',
  props: ['items'],
  components: {
    thirdLevel
  }
}
</script>

第三级组件:

<template>
  <ul class="nav-main-submenu">
    <li
      v-for="item in items"
      :key="item.id"
      class="nav-main-item"
    >
      <router-link :to="{ name: item.target }" class="nav-main-link">
        <font-awesome-icon
          :icon="item.icon"
          fixed-width
          class="nav-main-link-icon"
        />
        <span v-text="item.name" class="nav-main-link-name"></span>
      </router-link>
    </li>
  </ul>
</template>

<script>

export default {
  name: 'thirdLevel',
  props: ['items']
}
</script>

这里是一个截图,可以让您有更好的主意: menu screenshot

预期的行为应该是通过单击菜单项来定位目标,或者通过将open类添加/删除到li元素中来打开子菜单(如果存在)(类:{ {1}})。当您单击其他菜单项时,当前子菜单应关闭并打开新菜单。

感谢您的帮助。真的很感激。

0 个答案:

没有答案