Reputation: 603
I'm trying to make my navigation drawer to act as the following:
My navigation drawer:
<v-navigation-drawer v-model="drawer" bottom dense clipped app shapped>
<v-list nav dense flat v-for="item in navigationDrawerItens" :key="item.title">
<v-list-item
v-if="item.items == undefined"
:to="item.to"
link
active-class="primary--text text--primary-4"
:click="item.click"
>
<v-list-item-icon>
<v-icon>{{item.icon}}</v-icon>
</v-list-item-icon>
<v-list-item-title>{{item.title}}</v-list-item-title>
</v-list-item>
<v-list-group :prepend-icon="item.icon" no-action v-else>
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title v-text="item.title"></v-list-item-title>
</v-list-item-content>
</template>
<v-list-item
v-for="subItem in item.items"
:key="subItem.title"
:to="subItem.to"
link
active-class="primary--text text--primary-4"
>
<v-list-item-icon>
<v-icon>{{subItem.icon}}</v-icon>
</v-list-item-icon>
<v-list-item-title>{{subItem.title}}</v-list-item-title>
</v-list-item>
</v-list-group>
</v-list>
</v-navigation-drawer>
My navigationDrawerItems:
private navigationDrawerItens = [
{
title: 'Live',
icon: 'videocam',
click: this.getSettingsFromRest(),
to: '/live'
},
{
title: 'Settings',
icon: 'build',
click: this.getSettingsFromRest(),
to: '/settings'
},
{
title: 'About',
icon: 'info',
items: [{
title: 'Contact us',
to: '/contactus',
icon: 'contact_support'
}]
}
]
What I'm trying to say is: If I click on Settings and I was on Contact us, I would like to close the group About. If I was on Contact Us and I refresh the page, I would like to open the group About and Highlight Contact us
Upvotes: 1
Views: 4995
Reputation: 12466
Use group
in v-list-group
:
Assign a route namespace. Accepts a string or regexp for determining active state
Example
<v-list-group group="products">
<template v-slot:activator>
<v-list-item-title>Products</v-list-item-title>
</template>
<v-list-item to="/products/123">
<v-list-item-content> 123 </v-list-item-content>
</v-list-item>
<v-list-item to="/products/abc">
<v-list-item-content> abc </v-list-item-content>
</v-list-item>
</v-list-group>
Group Products
is active when current route matches '/products'.
E.g. http://localhost:3333/products/abc
Upvotes: 1
Reputation: 603
After chans help I manage to solve it like this:
<v-navigation-drawer v-model="drawer" bottom dense clipped app shapped>
<v-list nav dense flat v-for="item in navigationDrawerItems" :key="item.title">
<v-list-item
v-if="!item.items"
:to="item.to"
link
active-class="primary--text text--primary-4"
v-on:click="item.click;closeGroupIfActiveAfterClickingOnItem(item)"
>
<v-list-item-icon>
<v-icon>{{item.icon}}</v-icon>
</v-list-item-icon>
<v-list-item-title>{{item.title}}</v-list-item-title>
</v-list-item>
<v-list-group :prepend-icon="item.icon" no-action v-else v-model="item.active">
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title v-text="item.title"></v-list-item-title>
</v-list-item-content>
</template>
<v-list-item
v-for="subItem in item.items"
:key="subItem.title"
:to="subItem.to"
link
v-on:click="closeGroupIfActiveAfterClickingOnItem(item)"
active-class="primary--text text--primary-4"
>
<v-list-item-icon>
<v-icon>{{subItem.icon}}</v-icon>
</v-list-item-icon>
<v-list-item-title>{{subItem.title}}</v-list-item-title>
</v-list-item>
</v-list-group>
</v-list>
</v-navigation-drawer>
my code snippet:
private navigationDrawerItems = [
{
title: 'Live',
icon: 'videocam',
click: this.getSettingsFromRest(),
to: '/live'
},
{
title: 'Settings',
icon: 'build',
click: this.getSettingsFromRest(),
to: '/settings'
},
{
title: 'About',
icon: 'info',
active: false,
items: [{
title: 'Contact us',
to: '/contactus',
icon: 'contact_support'
}]
}]
private closeGroupIfActiveAfterClickingOnItem(pItem: any) {
for (let item of this.navigationDrawerItems) {
//This is a group
if (item.items) {
//Check if group is active AND we are not closing self
if (item.active && item.title != pItem.title) {
item.active = false
}
} else { continue }
}
}
private checkRoute() {
for (let item of this.navigationDrawerItems) {
if (item.items) {
for (let subItem of item.items) {
if (subItem.to == this.$route.fullPath) {
item.active = true
break
}
}
} else { continue }
}
}
Upvotes: 0
Reputation: 5260
Added some additional code for the above mentioned functionalities
Find the working codepen here: https://codepen.io/chansv/pen/QWWpYvK
<div id="app">
<v-app id="inspire">
<v-navigation-drawer :clipped="$vuetify.breakpoint.lgAndUp"
app
>
<v-list dense>
<template v-for="(item, ind) in items">
<v-list-item
v-if="!item.children"
:key="item.text"
@click="currentSelection = item.text"
:class="currentSelection == item.text ? 'grey': ''"
>
<v-list-item-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
{{ item.text }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-group
v-if="item.children"
:key="item.text"
v-model="item.model"
:prepend-icon="item.model ? item.icon : item['icon-alt']"
append-icon=""
>
<template v-slot:activator>
<v-list-item>
<v-list-item-content>
<v-list-item-title>
{{ item.text }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
<v-list-item
v-for="(child, i) in item.children"
:key="i"
@click="item.model = false;currentSelection = child.text"
:class="currentSelection == child.text ? 'grey': ''"
>
<v-list-item-action v-if="child.icon">
<v-icon>{{ child.icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
{{ child.text }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-group>
</template>
</v-list>
</v-navigation-drawer>
<v-container fluid>
<v-row justify="center" align="center">
<v-col cols="12" style="text-align: center;">
<v-card>
{{currentSelection}}
</v-card>
</v-col>
<v-row>
</v-container>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
currentSelection: '',
items: [
{ icon: 'contacts', text: 'Contacts' },
{ icon: 'history', text: 'Frequently contacted' },
{ icon: 'content_copy', text: 'Duplicates' },
{
icon: 'keyboard_arrow_up',
'icon-alt': 'keyboard_arrow_down',
text: 'More',
model: false,
children: [
{ text: 'Import' },
{ text: 'Export' },
{ text: 'Print' },
{ text: 'Undo changes' },
{ text: 'Other contacts' },
],
},
],
}),
created() {
this.currentSelection = this.items[0].text;
// retain the current route from this.$route.name or path and set it to current variable
var current = ''; // set from this.$route
// var current = 'Print'; // for testing comment above line and uncomment this line
if (current) {
var self = this;
this.items.forEach((item, i) => {
if (item.text == current) {
this.currentSelection = current;
}
if (item.children && item.children.length) {
if (item.children.map(x => x.text).includes(current)) {
self.items[i].model = true;
this.currentSelection = current;
}
}
})
}
}
})
Upvotes: 3