Carol Skelly
Posted on April 3, 2020
Lately I've been playing with Vue & Vuetify a lot so I decided to share this dashboard starter template. This may be helpful to kick start your next "admin" project, or as a basis for a creating simple collapsing sidebar layout with Vuetify.
Features
- Vue 2.x, Vuetify 2.2.x, Vue Router, Material Design Icons
- Light/Dark Theme Switcher
- Collapsing/Toggleable Sidebar
- Material Design Icons
Vue App and Router
I started with a typical Vue app and router set-up...
const routes = [
{ path:'/', component: Home },
{ path:'/detections', component: Page },
{ path:'/comp', component: Page },
{ path:'/customers', component: Page },
{ path:'/orders', component: Page },
{ path:'/settings', component: Page },
]
new Vue({
el: '#app',
router: new VueRouter({routes}),
vuetify: new Vuetify(),
})
App Layout
The overlay layout was 🍰 easy to achieve using Vuetify's v-app-bar
, v-navigation-drawer
and v-content
components...
<div id="app">
<v-app>
<v-app-bar app color="primary" dark>
..
</v-app-bar>
<v-navigation-drawer
app
floating
>
<v-list dense color="primary" dark>
...
</v-list>
</v-navigation-drawer>
<v-content>
<v-container fluid>
<v-row class="fill-height">
<v-col>
<transition name="fade">
<router-view></router-view>
</transition>
</v-col>
</v-row>
</v-container>
</v-content>
<v-footer>
...
</v-footer>
</v-app>
</div>
Next I fine tuned the Sidebar (v-navigation-drawer
) using a v-list
with items bound to my list of menu items
data. The toggling of the Sidebar is controlled with the sidebarMenu
menu boolean. You'll also see the toggleMenu
boolean for controlling the mini-variant prop Vuetify's navigation-drawer.
In my App.vue...
new Vue({
el: '#app',
data: () => ({
sidebarMenu: true,
toggleMini: false,
items: [
{ title:"Home", href:"/", icon:"mdi-home-outline" },
{ title:"Detections", href:"/detections", icon:"mdi-shield-account" },
{ title:"Components", href:"/comp", icon:"mdi-palette-swatch" },
{ title:"Customers", href:"/customers", icon:"mdi-account" },
{ title:"Orders", href:"/orders", icon:"mdi-bus-clock" },
{ title:"Settings", href:"/settings", icon:"mdi-settings-outline" },
],
})
})
<v-navigation-drawer
v-model="sidebarMenu"
app
floating
:permanent="sidebarMenu"
:mini-variant.sync="mini"
>
<v-list dense color="primary" dark>
<v-list-item>
<v-list-item-action>
<v-icon @click.stop="sidebarMenu = !sidebarMenu">mdi-chevron-left</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
<h3 class="font-weight-thin">Dashboard</h3>
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
<v-list-item class="px-2" @click="toggleMini = !toggleMini">
<v-list-item-avatar>
<v-icon>mdi-account-outline</v-icon>
</v-list-item-avatar>
<v-list-item-content class="text-truncate">
Jane Doeski
</v-list-item-content>
<v-btn icon small>
<v-icon>mdi-chevron-left</v-icon>
</v-btn>
</v-list-item>
<v-divider></v-divider>
<v-list>
<v-list-item v-for="item in items" :key="item.title" link :to="item.href">
<v-list-item-icon>
<v-icon color="primary">{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title class="primary--text">{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
Since I wanted the Sidebar (v-navigation-drawer
) to auto collapse to icons (the mini-variant) on smaller screens I added a mini
computed prop to control this. This value comes from Vuetify's breakpoint this.$vuetify.breakpoint.smAndDown
, otherwise the toggleMini
state that's already stored in our data
object...
new Vue({
el: '#app',
router: router,
vuetify: new Vuetify(),
computed: {
mini() {
return (this.$vuetify.breakpoint.smAndDown) || this.toggleMini
},
buttonText() {
return !this.$vuetify.theme.dark ? 'Go Dark' : 'Go Light'
}
},
data: () => ({
sidebarMenu: true,
toggleMini: false,
items: [
{ title:"Home", href:"/", icon:"mdi-home-outline" },
{ title:"Detections", href:"/detections", icon:"mdi-shield-account" },
{ title:"Components", href:"/comp", icon:"mdi-palette-swatch" },
{ title:"Customers", href:"/customers", icon:"mdi-account-search-outline" },
{ title:"Orders", href:"/orders", icon:"mdi-bus-clock" },
{ title:"Settings", href:"/settings", icon:"mdi-settings-outline" },
],
}),
methods: {
toggleTheme() {
this.$vuetify.theme.dark = !this.$vuetify.theme.dark;
},
}
})
Lastly I added the theme switcher logic. As you may know Vuetify has a light
or dark
theme option. I added a button to the app-bar
...
<v-app-bar app color="primary" dark elevation="0">
<v-app-bar-nav-icon @click.stop="sidebarMenu = !sidebarMenu"></v-app-bar-nav-icon>
<v-spacer></v-spacer>
<v-btn @click="toggleTheme" color="primary" class="mr-2">{{buttonText}}</v-btn>
<v-icon>mdi-account</v-icon>
</v-app-bar>
And the a method for the theme switch, and buttonText
computed value for the button...
computed: {
mini() {
return (this.$vuetify.breakpoint.smAndDown) || this.toggleMini
},
buttonText() {
return !this.$vuetify.theme.dark ? 'Go Dark' : 'Go Light'
}
},
methods: {
toggleTheme() {
this.$vuetify.theme.dark = !this.$vuetify.theme.dark;
},
}
Checkout the finished product on Codeply😎
Vuetify Dashboard Example
Full source: https://codeply.com/p/AtcbXz9Ybg
Light / Dark Theme Switch Example: https://codeply.com/p/AtcbXz9Ybg
Posted on April 3, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.