# 基本配置
| import { createRouter, createWebHistory } from 'vue-router'; |
| import pinia from './pinia'; |
| import { useUserStore } from '../store/user'; |
| |
| const user = useUserStore(pinia); |
| |
| |
| const constantRoutes = [ |
| { |
| |
| path: '/login', |
| name: 'login', |
| component: () => import('../views/login/index.vue') |
| }, |
| { |
| |
| path: '/:pathMatch(.*)', |
| name: 'notFound', |
| component: () => import('../views/error/notFound.vue') |
| }, |
| { |
| |
| path: '/noPermission', |
| name: 'noPermission', |
| component: () => import('../views/error/noPermission.vue') |
| } |
| ]; |
| |
| const asyncRoutes = { |
| path: '/', |
| name: 'main', |
| component: () => import('../views/mainPage.vue'), |
| children: [ |
| { |
| |
| path: '/', |
| name: 'home', |
| component: () => import('../views/home/index.vue') |
| }, |
| { |
| |
| path: '/settingUser', |
| name: 'settingUser', |
| component: () => import('../views/setting/user.vue') |
| } |
| ] |
| }; |
| |
| const router = createRouter({ |
| history: createWebHistory('/'), |
| routes: constantRoutes |
| }); |
| |
| router.addRoute(asyncRoutes); |
| |
| router.beforeEach((to, from, next) => { |
| |
| if (window.__axiosPromiseArr) { |
| window.__axiosPromiseArr.forEach((ele, ind) => { |
| ele.cancel(); |
| delete window.__axiosPromiseArr[ind]; |
| }); |
| } |
| |
| if (localStorage.getItem('expires') && (new Date().getTime() - localStorage.getItem('expires')) / 1000 > 1) { |
| this.$message.error('登录失效,请重新登录', () => { |
| localStorage.removeItem('userInfon'); |
| localStorage.removeItem('token'); |
| localStorage.removeItem('expires'); |
| location.href = '/login'; |
| }); |
| return; |
| } |
| |
| if (user.token) { |
| if (to.path === '/login') { |
| next({ path: '/' }); |
| } else { |
| |
| next(); |
| } |
| } else { |
| if (to.path === '/login') { |
| next(); |
| } else { |
| next({ name: 'login' }); |
| } |
| } |
| }); |
| |
| |
| router.afterEach(to => { |
| window.scrollTo(0, 0); |
| }); |
| |
| export default router; |
# 1. 安装 vue-router
# 2. 路由实例
创建路由实例,顺带初始化静态路由,而动态路由需要用户登录,根据用户拥有的角色进行权限校验后进行初始化。
| |
| import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'; |
| |
| export const Layout = () => import('@/layout/index.vue'); |
| |
| |
| export const constantRoutes: RouteRecordRaw[] = [ |
| { |
| path: '/redirect', |
| component: Layout, |
| meta: { hidden: true }, |
| children: [ |
| { |
| path: '/redirect/:path(.*)', |
| component: () => import('@/views/redirect/index.vue') |
| } |
| ] |
| }, |
| |
| { |
| path: '/login', |
| component: () => import('@/views/login/index.vue'), |
| meta: { hidden: true } |
| }, |
| |
| { |
| path: '/', |
| component: Layout, |
| redirect: '/dashboard', |
| children: [ |
| { |
| path: 'dashboard', |
| component: () => import('@/views/dashboard/index.vue'), |
| name: 'Dashboard', |
| meta: { title: 'dashboard', icon: 'homepage', affix: true } |
| } |
| ] |
| } |
| ]; |
| |
| |
| * 创建路由 |
| */ |
| const router = createRouter({ |
| history: createWebHashHistory(), |
| routes: constantRoutes as RouteRecordRaw[], |
| |
| scrollBehavior: () => ({ left: 0, top: 0 }) |
| }); |
| |
| |
| * 重置路由 |
| */ |
| export function resetRouter() { |
| router.replace({ path: '/login' }); |
| location.reload(); |
| } |
| |
| export default router; |
# 3. 全局注册路由实例
| |
| import router from "@/router"; |
| |
| app.use(router).mount('#app') |
# 4. 动态权限路由
路由守卫 src/permission.ts
,获取当前登录用户的角色信息进行动态路由的初始化
最终调用 permissionStore.generateRoutes(roles)
方法生成动态路由
| |
| import { listRoutes } from '@/api/menu'; |
| |
| export const usePermissionStore = defineStore('permission', () => { |
| const routes = ref<RouteRecordRaw[]>([]); |
| |
| function setRoutes(newRoutes: RouteRecordRaw[]) { |
| routes.value = constantRoutes.concat(newRoutes); |
| } |
| |
| * 生成动态路由 |
| * |
| * @param roles 用户角色集合 |
| * @returns |
| */ |
| function generateRoutes(roles: string[]) { |
| return new Promise<RouteRecordRaw[]>((resolve, reject) => { |
| |
| listRoutes() |
| .then(({ data: asyncRoutes }) => { |
| |
| const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles); |
| setRoutes(accessedRoutes); |
| resolve(accessedRoutes); |
| }) |
| .catch(error => { |
| reject(error); |
| }); |
| }); |
| } |
| |
| return { routes, setRoutes, generateRoutes }; |
| }); |
接口获取得到的路由数据
根据路由数据 (routes) 生成菜单的关键代码
src/layout/componets/Sidebar/index.vue | src/layout/componets/Sidebar/SidebarItem.vue |
---|
| |