Router & Nav
Router and Nav are the key skeleton for organizing an admin system.
In this project routes and nav are bound together while routes are auto-generated by vite-plugin-pages
according to your file system, so you only have to put the page components in @/pages
folder and then the routes, navigation sidebar and breadcrumbs will be generated automatically. This greatly reduces the workload of manually editing the navigation drawer. Of course, you need to follow some conventions in configuring the route.
Config
First let us know the meta to configure route. Add more types in route-meta.d.ts if you need more route meta.
declare module 'vue-router' {
interface RouteMeta {
icon?: string // drawer item icon
drawerGroup?: 'admin' | 'PUC' // groups are separated by line in drawer
drawerIndex?: number // determine the order of item in drawer
title?: string // drawer item and breadcrumb text
subtitle?: string // subtitle in drawer item
roles?: Role[] // authorized user groups
dataCy?: string // for cypress location
hidden?: boolean // hide this route in drawer if truthy
breadcrumb?: 'hidden' | 'disabled' // default is enabled
}
}
declare module 'vue-router' {
interface RouteMeta {
icon?: string // drawer item icon
drawerGroup?: 'admin' | 'PUC' // groups are separated by line in drawer
drawerIndex?: number // determine the order of item in drawer
title?: string // drawer item and breadcrumb text
subtitle?: string // subtitle in drawer item
roles?: Role[] // authorized user groups
dataCy?: string // for cypress location
hidden?: boolean // hide this route in drawer if truthy
breadcrumb?: 'hidden' | 'disabled' // default is enabled
}
}
Example
<route lang="json">
{
"meta": {
"title": "userManagement",
"icon": "$mdi-account-group",
"roles": ["admin"],
"drawerGroup": "admin"
}
}
</route>
<route lang="json">
{
"meta": {
"title": "userManagement",
"icon": "$mdi-account-group",
"roles": ["admin"],
"drawerGroup": "admin"
}
}
</route>
Nested Routes
If you have a nested route, such as @/pages/nested
, Don't forget to manually add a <RouterWrapper />
which contains a <router-view />
to the parent file with the same name as the secondary directory. You can refer to the example in this template.
Adding <RouterWrapper />
for every nested route parent is a little tedious. This can be avoid with the new feature in Vue Router v4.1 which, however, requires Vue 3 😒.
Navigation Drawer
The navigation drawer is mainly based on v-navigation-drawer
of Vuetify.
Also introduced in the front, the drawer is generated by routes and their meta. The drawer item is written as recursive component to support the infinite nesting of routes.
Note the drawer has already helped you to make a judgment. When a route have more than 1 child route, its corresponding drawer item will automatically become a nested one. If the number of sub-routes is exactly equal to one, that sub-route is displayed as a root route in the drawer.
Layout
All the pages except login page share the same layout with navigation drawer, header and footer. This uses vue-router
routing nesting, so in general, adding or modifying a page will only affect the main body (v-main
). Other content in the layout, such as the header or navigation drawer will not change with your main page.
/foo /bar
+------------------+ +-----------------+
| layout | | layout |
| +--------------+ | | +-------------+ |
| | foo.vue | | +------------> | | bar.vue | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
/foo /bar
+------------------+ +-----------------+
| layout | | layout |
| +--------------+ | | +-------------+ |
| | foo.vue | | +------------> | | bar.vue | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
With the help of vite-plugin-vue-layout
, we don't need to manually add a parent layout component for every first-level route. The plugin works along with vite-plugin-pages
and will transform the original router. If you want to change the layout for a specific page, add or modify layout
meta in route block.
<route lang="yaml">
meta:
layout: users
</route>
<route lang="yaml">
meta:
layout: users
</route>