带有子菜单的Vuetify导航抽屉

时间:2019-04-03 20:22:03

标签: vue.js vuetify.js

就像标题中所说的那样,我正在尝试使用一个导航抽屉,该抽屉具有某些选项的可扩展子菜单。像“用户个人资料”一样,主菜单选项可能具有子菜单“更新联系人详细信息”和“审阅注册”。

我已经尝试了几种方法,基本上可以归结为两个相同的问题。由于每个菜单选项都是一个列表块,因此子菜单会堆叠在其右侧(例如,整个子菜单位于同一图块中),或者整个菜单选项列表都具有这些下拉图标,当只有一个菜单选项实际上有一个子菜单时。另外,下面的第二个代码段也使您无法导航到任何主菜单链接,这不是所需要的。

示例1,其中子菜单与主菜单选项位于同一图块中。

<div v-for="(link, i) in links" :key="i">
    <v-list-tile v-if="!link.subLinks" :to="link.to" :active-class="color" avatar class="v-list-item">
        <v-list-tile-action>
            <v-icon>{{ link.icon }}</v-icon>
        </v-list-tile-action>
        <v-list-tile-title v-text="link.text"/>
    </v-list-tile>

    <div v-else>
        <v-list-tile avatar class="v-list-item">
            <v-list-tile-action>
                <v-icon>{{ link.icon }}</v-icon>
            </v-list-tile-action>
            <v-list-tile-title v-text="link.text"/>
            <v-list-group>
                <v-list-tile sub-group v-for="(subLink, j) in link.subLinks" :key="j" :to="subLink.to" :active-class="color" avatar class="v-list-item">
                    <v-list-tile-title v-text="subLink.text"/>
                </v-list-tile>
            </v-list-group>
         </v-list-tile>
     </div>
</div>

示例2,其中每个菜单选项都有一个下拉箭头,甚至是没有任何子菜单的箭头。

<v-list-group v-for="(link, i) in links" :key="i" :prepend-icon="link.icon" :to="link.to" :active-class="color" avatar class="v-list-item">
    <template v-slot:activator>
        <v-list-tile>
            <v-list-tile-title>{{ link.text }}</v-list-tile-title>
        </v-list-tile>
    </template>

    <v-list-tile v-for="(subLink, j) in link.subLinks" :key="j" :to="subLink.to" :active-class="color">
        <v-list-tile-content>
            <v-list-tile-title>{{ subLink.text }}</v-list-tile-title>
        </v-list-tile-content>
    </v-list-tile>
</v-list-group>

这是我正在使用的数据的示例

links: [
    {
        to: '/',
        icon: 'mdi-view-dashboard',
        text: 'Dashboard',
    },
    {
        icon: 'mdi-account',
        text: 'User Profile',
        subLinks: [
            {
                to: '/update-contact',
                text: 'Update Contact Details',
            },
            {
                to: '/review-registration',
                text: 'Review Registration',
            },
        ],
    },
],

我想做的是有一个主菜单,并可以选择添加子菜单。不幸的是,我似乎无法弄清楚如何混合和匹配列表组和列表平铺来完成我想做的事情。我非常感谢您提供的任何帮助。谢谢。

4 个答案:

答案 0 :(得分:4)

我没有足够的声誉来添加评论,但这将为您提供更好的布局和正确的功能(在上面发布的链接中,由于某些原因,链接不起作用,并且命名有些偏离)

<template>
    <v-navigation-drawer
      app
      clipped
      permanent
      mini-variant
      expand-on-hover>
      <!-- -->

      <v-list nav dense>
       <div v-for="(link, i) in links" :key="i">

        <v-list-item
            v-if="!link.subLinks"
            :to="link.to"
            :active-class="color"
            avatar
            class="v-list-item"
        >
            <v-list-item-icon>
                <v-icon>{{ link.icon }}</v-icon>
            </v-list-item-icon>

            <v-list-item-title v-text="link.text" />
        </v-list-item>

        <v-list-group
            v-else
            :key="link.text"
            no-action
            :prepend-icon="link.icon"
            :value="false"
        >
            <template v-slot:activator>
              <v-list-item-title>{{ link.text }}</v-list-item-title>
             </template>

            <v-list-item
                v-for="sublink in link.subLinks"
                :to="sublink.to"
                :key="sublink.text"
            >
                <v-list-item-icon>
                  <v-icon>{{ sublink.icon }}</v-icon>
                </v-list-item-icon>
                <v-list-item-title>{{ sublink.text }}</v-list-item-title>

            </v-list-item>

        </v-list-group>

    </div>

      </v-list>

    </v-navigation-drawer>
</template>

<script>
export default {
  data: () => ({
links: [
    {
        to     : '/dashboard',
        icon   : 'mdi-view-dashboard',
        text   : 'Dashboard',
    },
    {
        icon     : 'mdi-folder',
        text     : 'Templates',
        subLinks : [
            {
                text : 'View Templates',
                to    : '/templates',
                icon  : 'mdi-view-list'
            },
            {
                text : 'New Template',
                to    : '/templates/new',
                icon  : 'mdi-plus'
            },
        ]
    },
    {
        icon     : 'mdi-application',
        text     : 'Applications',
        subLinks : [
            {
                text : 'View Applications',
                to    : '/apps',
                icon  : 'mdi-view-list'
            },
            {
                text : 'New Application',
                to    : '/apps',
                icon  : 'mdi-plus'
            },
        ]
    },
]
  })
}
</script>

<style scoped>
.v-application--is-ltr .v-list--dense.v-list--nav .v-list-group--no-action > .v-list-group__items > .v-list-item {
  padding: 0 8px;
}
</style>

答案 1 :(得分:3)

希望这会有所帮助。 基本上,导航抽屉组件(v-navigation-drawer)上的菜单使用列表组件(v-list)。

从文档中,您可以找到在列表组件上添加子菜单的方法 on the part of nested list

干杯

答案 2 :(得分:2)

我一直想做同样的事情,这就是我的解决方法。

数据:

links: [
    {
        to     : '/dashboard',
        icon   : 'mdi-view-dashboard',
        text   : 'Dashboard',
    },
    {
        icon     : 'mdi-tennis',
        text     : 'Players',
        subLinks : [
            {
                text : 'Players list',
                to    : '/players',
            },
            {
                text : 'Import WTA Players',
                to    : '/players/import',
            },
        ]
    },
    {
        to     : '/tournaments',
        icon   : 'mdi-trophy',
        text   : 'Tournaments',
    },
]

模板:

<v-list>
    <div v-for="(link, i) in links">

        <v-list-tile
            v-if="!link.subLinks"
            :key="i"
            :to="link.to"
            :active-class="color"
            avatar
            class="v-list-item"
        >
            <v-list-tile-action>
                <v-icon>{{ link.icon }}</v-icon>
            </v-list-tile-action>

            <v-list-tile-title v-text="link.text" />
        </v-list-tile>

        <v-list-group
            v-else
            :key="link.text"
            no-action
        >
            <template v-slot:activator>
               <v-list-tile>
                 <v-list-tile-content>
                   <v-list-tile-title>{{ link.text }}</v-list-tile-title>
                 </v-list-tile-content>
               </v-list-tile>
             </template>

            <v-list-tile
                v-for="sublink in link.subLinks"
                :to="sublink.to"
                :key="sublink.text"
            >
                <v-list-tile-title v-text="sublink.text" />
            </v-list-tile>

        </v-list-group>

    </div>
</v-list>

对不起,但我没有时间来动笔。希望这会有所帮助!

答案 3 :(得分:0)

我刚刚找到了一种设置子菜单活动类的方法。希望它可以帮助其他人。 感谢 VueJS-Linusborg。

<template>
......
<v-list-group
  v-else
  :key="link.text"
  no-action
  :prepend-icon="link.icon"
  :value="subIsActive('/parentroute')"
>
<template v-slot:activator>
  <v-list-item-title>{{ link.text}}</v-list-item-title>
</template>
    
<v-list-item
  v-for="sublink in link.subLinks"
  :to="sublink.to"
  :key="sublink.text"
  :active-class="`success white--text`"
>
 <v-list-item-icon>
   <v-icon>{{ sublink.icon }}</v-icon>
 </v-list-item-icon>
 <-list-item-title>{{ sublink.text}}</v-list-item-title>
 </v-list-item>
</v-list-group>
...
</template>
<script>
...
methods:{
  subIsActive(input) {
    const paths = Array.isArray(input) ? input : [input];
    return paths.some((path) => {
    return this.$route.path.indexOf(path) === 0; // current path starts with this path 
    string
  });
},
....
}</script>