Routes and Menus
The project provides a basic routing system that can dynamically generate menu structures and dynamically register routes based on configuration files.
Route Types
The routes in the project are divided into two categories: Static Routes and Dynamic Routes.
Static Routes: Determined when the project starts, usually including public pages such as login page, 404, etc.
Dynamic Routes: Dynamically generated after user login, based on the menu data returned by the backend, usually used to control permissions and personalized navigation.
Static Routes
Basic page routes that can be accessed without permission, such as: login page, registration page, 404, 500, etc.
Configuration location: src/router/routes/staticRoutes.ts
Route Variable:
const staticRoutes: AppRouteRecordRaw[] = [];
Dynamic Routes
Business page routes that require permission control, such as: user management, menu management, etc.
Configuration location: src/router/routes/asyncRoutes.ts
const asyncRoutes: MenuListType[] = [];
Route Definition
The definition methods for static routes and dynamic routes are basically the same. See the example below:
Static Routes
Static Route Configuration
export const staticRoutes: AppRouteRecordRaw[] = [
{
path: "/",
redirect: HOME_PAGE,
},
{
path: RoutesAlias.Login,
name: "Login",
component: () => import("@views/auth/login/index.vue"),
meta: { title: "menus.login.title", isHideTab: true, setTheme: true },
},
{
path: RoutesAlias.Register,
name: "Register",
component: () => import("@views/auth/register/index.vue"),
meta: {
title: "menus.register.title",
isHideTab: true,
noLogin: true,
setTheme: true,
},
},
{
path: RoutesAlias.ForgetPassword,
name: "ForgetPassword",
component: () => import("@views/auth/forget-password/index.vue"),
meta: {
title: "menus.forgetPassword.title",
isHideTab: true,
noLogin: true,
setTheme: true,
},
},
{
path: "/exception",
component: Home,
name: "Exception",
meta: { title: "menus.exception.title" },
children: [
{
path: RoutesAlias.Exception403,
name: "Exception403",
component: () => import("@views/exception/403/index.vue"),
meta: { title: "403" },
},
{
path: "/:catchAll(.*)",
name: "Exception404",
component: () => import("@views/exception/404/index.vue"),
meta: { title: "404" },
},
{
path: RoutesAlias.Exception500,
name: "Exception500",
component: () => import("@views/exception/500/index.vue"),
meta: { title: "500" },
},
],
},
];
Dynamic Routes
Dynamic Route Configuration
export const asyncRoutes: AppRouteRecord[] = [
{
name: "Dashboard",
path: "/dashboard",
component: RoutesAlias.Home,
meta: {
title: "menus.dashboard.title",
icon: "",
},
children: [
{
path: "console",
name: "Console",
component: RoutesAlias.Dashboard,
meta: {
title: "menus.dashboard.console",
keepAlive: false,
fixedTab: true,
},
},
{
path: "analysis",
name: "Analysis",
component: RoutesAlias.Analysis,
meta: {
title: "menus.dashboard.analysis",
keepAlive: false,
},
},
{
path: "ecommerce",
name: "Ecommerce",
component: RoutesAlias.Ecommerce,
meta: {
title: "menus.dashboard.ecommerce",
keepAlive: false,
},
},
],
},
];
Dynamic Routes
Dynamic Route Configuration
export const asyncRoutes: AppRouteRecord[] = [
{
name: "Dashboard",
path: "/dashboard",
component: RoutesAlias.Home,
meta: {
title: "menus.dashboard.title",
icon: "",
},
children: [
{
path: "console",
name: "Console",
component: RoutesAlias.Dashboard,
meta: {
title: "menus.dashboard.console",
keepAlive: false,
fixedTab: true,
},
},
{
path: "analysis",
name: "Analysis",
component: RoutesAlias.Analysis,
meta: {
title: "menus.dashboard.analysis",
keepAlive: false,
},
},
{
path: "ecommerce",
name: "Ecommerce",
component: RoutesAlias.Ecommerce,
meta: {
title: "menus.dashboard.ecommerce",
keepAlive: false,
},
},
],
},
// First-level menu
{
name: "ChangeLog",
path: "/change/log",
component: RoutesAlias.ChangeLog,
meta: {
title: "menus.plan.log",
showTextBadge: `v${__APP_VERSION__}`,
icon: "",
keepAlive: false,
},
},
];
Nested Routes
Nested Routes Configuration
{
path: '/system',
name: 'System',
component: RoutesAlias.Home,
meta: {
title: 'menus.system.title',
icon: '',
roles: ['R_SUPER', 'R_ADMIN']
},
children: [
{
path: 'nested',
name: 'Nested',
component: '',
meta: {
title: 'menus.system.nested',
keepAlive: true
},
children: [
{
path: 'menu1',
name: 'NestedMenu1',
component: RoutesAlias.NestedMenu1,
meta: {
title: 'menus.system.menu1',
icon: '',
keepAlive: true
}
},
{
path: 'menu2',
name: 'NestedMenu2',
component: '',
meta: {
title: 'menus.system.menu2',
icon: '',
keepAlive: true
},
children: [
{
path: 'menu2-1',
name: 'NestedMenu2-1',
component: RoutesAlias.NestedMenu21,
meta: {
title: 'menus.system.menu21',
icon: '',
keepAlive: true
}
}
]
},
{
path: 'menu3',
name: 'NestedMenu3',
component: '',
meta: {
title: 'menus.system.menu3',
icon: '',
keepAlive: true
},
}
]
}
]
}
Creating a New Page
You only need to create a page in the /src/views/ directory, such as: /src/views/safeguard/Server.vue
<template>
<div class="page-content">
<h1>test page</h1>
</div>
</template>
Tips: In the example above, we added a page with the class name class="page-content"
, which ensures the box's minimum height always fills the remaining screen height.
Route Registration
After creating a page, you need to register the route to access the page.
Configuration file: src/router/routes/asyncRoutes.ts
First-level Route (First-level Menu):
export const asyncRoutes: MenuListType[] = [
{
path: "/test/index",
name: "Test",
component: "/test/index",
meta: {
title: "Test Page",
keepAlive: true,
},
},
];
After completing the steps above, you can access the page.
At this point, the route addition is complete. Visit http://localhost:3006/safeguard/server, and if you can access it normally, it indicates that the route and menu definition is successful.
Multi-level Routes (Multi-level Menus):
export const asyncRoutes: MenuListType[] = [
{
name: "Form",
path: "/form",
component: RoutesAlias.Home,
meta: {
title: "Form",
icon: "",
keepAlive: false,
},
children: [
{
path: "basic",
name: "Basic",
component: "/form/basic",
meta: {
title: "Basic Form",
keepAlive: true,
},
},
{
path: "step",
name: "Step",
component: "/form/step",
meta: {
title: "Step Form",
keepAlive: true,
},
},
],
},
];
Static Route Configuration:
Configuration file path: src/router/routes/staticRoutes.ts
export const staticRoutes: AppRouteRecordRaw[] = [
{
path: "/test",
name: "Test",
component: () => import("@views/test/index.vue"),
meta: { title: "Test Page", isHideTab: true, setTheme: true },
},
];
After configuration, you can visit: http://localhost:3006/#/test to view the newly created page. At this point, the static route registration is complete. Tips: If a static route is also configured in the dynamic route table, you need to remove the configuration from the static route, as dynamic routes will automatically register routes.
Homepage Configuration
You can define the homepage route by configuring the HOME_PAGE
property. Configuration file path: src/router/routesAlias.ts
export const HOME_PAGE = RoutesAlias.Dashboard;
Route and Menu Types
export type MenuListType = {
id: number; // id
path: string; // route path
name: string; // component name
component?: string; // component path
meta: {
/** Route title */
title: string;
/** Route icon */
icon?: string;
/** Whether to display badge */
showBadge?: boolean;
/** Text badge */
showTextBadge?: string;
/** Whether to hide in menu */
isHide?: boolean;
/** Whether to hide in tab */
isHideTab?: boolean;
/** External link */
link?: string;
/** Whether it is an iframe */
isIframe?: boolean;
/** Whether to cache */
keepAlive?: boolean;
/** Operation permissions */
authList?: Array<{
/** Permission name */
title: string;
/** Permission identifier */
auth_mark: string;
}>;
/** Whether it is a first-level menu (no need to configure manually, automatically identified) */
isFirstLevel?: boolean;
/** Role permissions */
roles?: string[];
/** Whether to fix the tab */
fixedTab?: boolean;
};
children?: MenuListType[]; // child routes
};
meta
meta is the metadata of the menu, used to define the display and behavior of the menu. It includes the following properties:
title
- Type:
string
- Description: Route title
icon
- Type:
string
- Description: Route icon
showBadge
- Type:
boolean
- Description: Whether to display badge
showTextBadge
- Type:
string
- Description: Text badge
isHide
- Type:
boolean
- Description: Whether to hide in menu
isHideTab
- Type:
boolean
- Description: Whether to hide in tab
link
- Type:
string
- Description: External link
isIframe
- Type:
boolean
- Description: Whether it is an iframe
keepAlive
- Type:
boolean
- Description: Whether to cache
authList
- Type:
Array<{title: string, auth_mark: string}>
- Description: Operation permissions list, including permission name and permission identifier
isFirstLevel
- Type:
boolean
- Description: Whether it is a first-level menu, no need to configure manually, automatically identified
roles
- Type:
string[]
- Description: Role permissions
fixedTab
- Type:
boolean
- Description: Whether to fix the tab