实现内容:
1.根据后台返回的菜单,前端实现动态添加路由;
2.解决刷新页面时,路由消失/页面空白的问题;
第一步:请求后台,返回菜单数据【内容如下】
// 后台返回的菜单数据 this.menuList = [ { id: 1, path: '/home', name: '首页', icon: true, children: [], component: '/home/home' }, { id: 12, path: '/pinia', name: 'pinia的使用', icon: true, children: [], component: '/pinia/pinia' }, { id: 2, path: '/menu', name: '递归菜单页面', icon: true, children: [], component: '/recursion-menu/recursion-menu' }, { id: 3, path: '/test', name: '测试', icon: true, children: [], component: '/test/test' }, { id: 10, path: '/permisson', name: '权限管理', icon: true, children: [ { id: '10-1', path: '/user', name: '用户管理', children: [], component: '/promission/user-manage' }, { id: '10-2', path: '/role', name: '角色管理', children: [], component: '/promission/roles-manage' } ] } ]
复制
第二步:根据菜单数据,动态添加到路由信息中
1.静态路由【routes.ts文件】
import { RouteRecordRaw } from 'vue-router' const Login = () => import('@/views/login/login.vue') const Home = () => import('@/views/home/home.vue') const Layout = () => import('@/layout/layout.vue') const Page404 = () => import('@/views/error/page404.vue') // 基础路由,不需要设置权限 export const basicRoutes:RouteRecordRaw[] = [ { path: '/login', name: 'login', component: Login }, { path: '/', name: 'layout', component: Layout, meta: { requiresAuth: true // 在这里设置,表示layout下边的子路由全部需要登录才能访问 }, redirect: '/home', children: [ { path: '/home', name: 'home', component: Home } ] }, { path: '/:pathMatch(.*)', name: 'page404', component: Page404 } ]
复制
2.基础路由信息【index.ts】
import { createRouter, createWebHashHistory } from 'vue-router' import { basicRoutes } from '@/router/routes' import { App } from 'vue' import { setupRouterHooks } from '@/router/routerHooks' export const router = createRouter({ history: createWebHashHistory(), routes: basicRoutes }) export function setupRouter (app: App<Element>): void { // 路由钩子函数 setupRouterHooks() app.use(router) } export default router
复制
3.将数据动态添加到路由信息中【routerHooks.ts文件】
addRoutes(this.menuList) // 此处的menuList为上述中返回的数据 import { router } from '@/router/index' import type { MenuItem } from '@/pinia/modules/menu' import { RouteRecordRaw } from 'vue-router' // vue3 + vite中的动态引入组件的方法 const loadView = import.meta.glob('../views/**/*.vue') // 动态添加路由 export function addRoutes (menu: MenuItem[]) { menu.forEach(e => { // 只将页面信息添加到路由中 if (!e.children || e.children.length === 0) { router.addRoute('layout', { name: e.path.slice(1), path: e.path, meta: { title: e.name }, component: loadView[`../views${e.component}.vue`] }) } else { addRoutes(e.children) } }) }
复制
第三步:添加路由钩子,解决页面刷新,路由消失的问题【routerHelper.ts】
import { router } from '@/router/index' import nprpgreee from 'nprogress' import 'nprogress/nprogress.css' import { useMenuStoreWithOut } from '@/pinia/modules/menu' const menuStore = useMenuStoreWithOut() export function setupRouterHooks () { router.beforeEach((to, from, next) => { nprpgreee.start() // 开始加载进度条 if (to.path === '/login') { next() } else { // 页面刷新时,重新加载路由 if (menuStore.menuList.length === 0) { menuStore.setMenuList() next({ path: to.path }) // next({ ...to, replace: true }) //此方法不生效 } else { next() } } }) router.afterEach(() => { nprpgreee.done() }) }
复制