Navigation drawers are useful for navigating through a web application. They provide an easily accessible means of quickly jumping from one location to another. In this article, we’ll learn how we can create and customize navigation drawers with Vuetify.
The v-navigation-drawer Component
We create navigation drawers in Vuetify with the v-navigation-drawer
component. We set the app
prop on this component to indicate to the Vuetify framework that it is part of the application layout.
<template>
<v-app>
<v-app-bar color="green" class="flex-grow-0" app dark>
<v-app-bar-title>Coding Beauty</v-app-bar-title>
</v-app-bar>
<v-navigation-drawer app>
<v-list-item>
<v-list-item-content>
<v-list-item-title class="text-h6"> Learning Vuetify </v-list-item-title>
<v-list-item-subtitle> Navigation drawers</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-divider></v-divider>
<v-list dense nav>
<v-list-item v-for="item in items" :key="item.title" link>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
items: [
{ title: 'Dashboard', icon: 'mdi-view-dashboard' },
{ title: 'Account', icon: 'mdi-account-box' },
{ title: 'Settings', icon: 'mdi-cog' },
],
}),
};
</script>
Temporary Navigation Drawers in Vuetify
Navigation drawers don’t have to be fixed. We can use a variable to toggle its visibility through v-model
. We do this in the code below when the v-app-bar-nav-icon
is selected. Apart from setting this variable to false
, clicking outside of an open navigation drawer can also close it.
<template>
<v-app>
<v-app-bar color="primary" class="flex-grow-0" app dark>
<v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-app-bar-title>Coding Beauty</v-app-bar-title>
</v-app-bar>
<v-navigation-drawer app v-model="drawer">
<v-list-item>
<v-list-item-content>
<v-list-item-title class="text-h6"> Learning Vuetify</v-list-item-title>
<v-list-item-subtitle> Using Navigation drawers</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-divider></v-divider>
<v-list dense nav>
<v-list-item v-for="item in items" :key="item.title" link>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
drawer: false,
items: [
{ title: 'Dashboard', icon: 'mdi-view-dashboard' },
{ title: 'Account', icon: 'mdi-account-box' },
{ title: 'Settings', icon: 'mdi-cog' },
],
}),
};
</script>
Customizing Navigation Drawer Colors in Vuetify
We can use varying color styles on our navigation drawers with the color
prop. With the dark
prop, we can also make the text contained in the drawer light or dark, to blend in properly with its background color:
<template>
<v-app>
<v-app-bar color="primary" class="flex-grow-0" app dark>
<v-app-bar-title>Coding Beauty</v-app-bar-title>
</v-app-bar>
<v-navigation-drawer app color="green" dark>
<v-divider></v-divider>
<v-list dense nav>
<v-list-item v-for="item in items" :key="item.title" link>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
items: [
{ title: 'Dashboard', icon: 'mdi-view-dashboard' },
{ title: 'Account', icon: 'mdi-account-box' },
{ title: 'Settings', icon: 'mdi-cog' },
],
}),
};
</script>
Bottom Navigation Drawers in Vuetify
We can relocate the navigation drawer to come from the bottom of the screen on mobile devices, by setting the bottom
prop to true
. This alternative style only activates when its mobile-breakpoint
is met.
<template>
<v-app>
<v-app-bar color="primary" class="flex-grow-0" app dark>
<v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-app-bar-title>Coding Beauty</v-app-bar-title>
</v-app-bar>
<v-navigation-drawer app v-model="drawer" bottom>
<v-list-item>
<v-list-item-content>
<v-list-item-title class="text-h6"> Learning Vuetify</v-list-item-title>
<v-list-item-subtitle> Using Navigation drawers</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-divider></v-divider>
<v-list dense nav>
<v-list-item v-for="item in items" :key="item.title" link>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
drawer: false,
items: [
{ title: 'Dashboard', icon: 'mdi-view-dashboard' },
{ title: 'Account', icon: 'mdi-account-box' },
{ title: 'Settings', icon: 'mdi-cog' },
],
}),
};
</script>
Vuetify Navigation Drawer Mini Variant
With the mini-varian
t prop, we can reduce the size of the drawer and only show the first element of each of the elements inside the v-list
. The drawer reduces to a size of 56px by default.
<template>
<v-app>
<v-app-bar color="primary" class="flex-grow-0" app dark>
<v-app-bar-title>Coding Beauty</v-app-bar-title>
</v-app-bar>
<v-navigation-drawer app mini-variant>
<v-divider></v-divider>
<v-list dense nav>
<v-list-item v-for="item in items" :key="item.title" link>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
items: [
{ title: 'Dashboard', icon: 'mdi-view-dashboard' },
{ title: 'Account', icon: 'mdi-account-box' },
{ title: 'Settings', icon: 'mdi-cog' },
],
}),
};
</script>
Expanding Navigation Drawers on Hover
If we want a navigation drawer of the mini-variant to expand on hover, we can set the expand-on-hover
property to true
:
<template>
<v-app>
<v-app-bar color="primary" class="flex-grow-0" app dark>
<v-app-bar-title>Coding Beauty</v-app-bar-title>
</v-app-bar>
<v-navigation-drawer app expand-on-hover>
<v-divider></v-divider>
<v-list dense nav>
<v-list-item v-for="item in items" :key="item.title" link>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
items: [
{ title: 'Dashboard', icon: 'mdi-view-dashboard' },
{ title: 'Account', icon: 'mdi-account-box' },
{ title: 'Settings', icon: 'mdi-cog' },
],
}),
};
</script>
Right-aligned Navigation Drawers in Vuetify
Setting the right
prop to true
on the navigation drawer component will align it to the right of the screen instead of the default left.
<template>
<v-app>
<v-app-bar color="red" class="flex-grow-0" app dark>
<v-app-bar-title>Coding Beauty</v-app-bar-title>
</v-app-bar>
<v-navigation-drawer app right>
<v-list-item>
<v-list-item-content>
<v-list-item-title class="text-h6"> Learning Vuetify </v-list-item-title>
<v-list-item-subtitle> Navigation drawers</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-divider></v-divider>
<v-list dense nav>
<v-list-item v-for="item in items" :key="item.title" link>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
items: [
{ title: 'Dashboard', icon: 'mdi-view-dashboard' },
{ title: 'Account', icon: 'mdi-account-box' },
{ title: 'Settings', icon: 'mdi-cog' },
],
}),
};
</script>
Permanent Navigation Drawers
By default, navigation drawers get hidden once its mobile-breakpoint
is met:
We can prevent this using the permanent
prop:
<template>
<v-app>
<v-app-bar color="indigo" class="flex-grow-0" app dark>
<v-app-bar-title>Coding Beauty</v-app-bar-title>
</v-app-bar>
<v-card elevation="12">
<v-navigation-drawer app permanent>
<v-list-item>
<v-list-item-content>
<v-list-item-title class="text-h6">
Learning Vuetify
</v-list-item-title>
<v-list-item-subtitle> Navigation drawers</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-divider></v-divider>
<v-list dense nav>
<v-list-item v-for="item in items" :key="item.title" link>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-card>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
items: [
{ title: 'Dashboard', icon: 'mdi-view-dashboard' },
{ title: 'Account', icon: 'mdi-account-box' },
{ title: 'Settings', icon: 'mdi-cog' },
],
}),
};
</script>
Summary
Similar to tabs, navigation drawers can be used to add an additional layer of navigation to your web applications. Vuetify provides the v-navigation-drawer
component for creating them, with various props for customization.
Every Crazy Thing JavaScript Does
A captivating guide to the subtle caveats and lesser-known parts of JavaScript.