赞
踩
[前端项目] 中的路由,很有可能是需要动态注册的。因为菜单可能在管理系统中维护,还跟权限绑定,用户登录以后,需要动态展示菜单。菜单往往跟路由挂钩,因此,路由需要动态注册router.addRoute 进行添加import Vue from 'vue' import VueRouter from 'vue-router' import Main from '@/views/Main' import Role1 from '@/views/role/role1' import store from '@/store' Vue.use(VueRouter) // 静态路由 export const constantRoutes = [ { path: '/login', name: 'login', component: () => import( "@/views/LoginPage"), meta: { keepAlive: true, isTab: false, isAuth: false, }, }, { path: '/', component: Main, name: 'Main', redirect: '/home', children: [ ] }, { path: '/404', name: '404', component: () => import('@/views/error/404'), hidden: true }, { path: '/401', name: '401', component: () => import( '@/views/error/401'), hidden: true }, // { // path: "*", // redirect: "/404", // }, ] const router = new VueRouter({ mode: 'hash', scrollBehavior: () => ({ y: 0 }), routes:constantRoutes }) // 解决ElementUI报重复点击菜单错误 const originalPush = router.push router.push = function push(location) { return originalPush.call(this, location).catch(err => err) } export default router
这里需要注意一下

import { login, logout, getInfo } from '@/api/login' import { getStore, setStore, clearStore, removeStore } from '@/util/storage' import { deepClone } from '@/util/validate' import router from '@/router'; // 动态菜单 多层嵌套 const generateRoutes = (menuList, parentPath = '') => { return menuList.map(menuItem => { const fullPath = parentPath + menuItem.menuPath; const route = { path: fullPath, component: () => import(`@/views/${menuItem.menuComponentPath}`), name: menuItem.menuName, meta: { title: menuItem.menuTitle, noCache: true, icon: menuItem.menuIconName }, id: menuItem.id }; if (menuItem.children && menuItem.children.length > 0) { route.children = generateRoutes(menuItem.children, fullPath + '/'); } router.addRoute("Main",route); return route; }); }; // 扁平化动态路由 const flattening=(menuTree)=>{ console.log(menuTree,'menuTree'); let tempArray =[] menuTree.forEach(ele=>{ tempArray.push(ele) // 递归处理 if (ele.children) { tempArray.push(...flattening(ele.children)); } }) return tempArray } const user = { state: { meun:getStore({ name: 'menu' }) || [], }, mutations: { SET_MENU(state, menu) { state.menu = menu setStore({ name: 'menu', content: menu, type: 'session' }) }, }, actions: { // 获取用户信息 GetInfo({ commit, state }) { return new Promise((resolve, reject) => { getInfo().then(res => { console.log(res.data, 'GetInfo'); const menu = deepClone(res.data.menus); const menus = generateRoutes(menu); // 生成动态菜单 const roles = flattening(menus) console.log(menus,roles,'routes'); commit('SET_MENU', menus) resolve(res) }).catch(error => { reject(error) }) }) }, } } export default user


这个是后端给的接口

这个是登录成功之后 后端返回的数据

我们需要对这个数据进行处理 用于 侧边栏 头部导航 还有动态路由 的配置

因为后端给到的数据不是路由表里面 一一对应的 path name 等键值对的形式,就需要自行处理
[ { "path": "/home", "name": "Home", "meta": { "title": "首页", "noCache": true }, "id": 1 }, { "path": "/n1", "name": "Nested1", "meta": { "title": "Nested1", "noCache": true }, "id": 3, "children": [ { "path": "/n1/n2", "name": "Nested2", "meta": { "title": "Nested2", "noCache": true }, "id": 4 } ] }, { "path": "/test", "name": "Test", "meta": { "title": "test", "noCache": true }, "id": 2 } ]

这个时候就存储一下,就可以直接使用了
我们在这里的时候就可以addRoute了,然后在页面中打印

注意
router.addRoute() 添加路由之后,通过router.options.routers 是查看不到添加的动态路由信息router.getRoutes() 可以查看到

正常

刷新

这里需要 去 路由守卫 router.beforeEach 里面去处理

/** * 全站权限配置 * */ import router from '@/router' import store from '@/store' import Layout from '@/views/Main' import { getStore, setStore, clearStore, removeStore } from '@/util/storage' import NProgress from 'nprogress' // progress bar import 'nprogress/nprogress.css' // progress bar style NProgress.configure({ showSpinner: false }) /** * 导航守卫,相关内容可以参考: * https://router.vuejs.org/zh/guide/advanced/navigation-guards.html */ // 记录路由 let hasRoles =true router.beforeEach(async(to, from, next) => { NProgress.start() // 判断token const token = getStore({ name: 'access_token' }) if (!token && to.name !== 'login') { next({ name: 'login' }) NProgress.done() } else if (token && to.name == 'login') { // 跳转页面 next({ path: '/' }) NProgress.done() } else { if(token && hasRoles){ await store.dispatch("GetInfo") hasRoles =false next({...to,replace:true}) }else{ next() } NProgress.done() } }) router.afterEach(() => { NProgress.done() })
就不会出现白屏问题了,正常刷新正常有
关于 通配符 404页面,我的处理是在动态路由都添加进去之后在了添加
也是在 permission.js 中添加的

tip 可能遇到的问题
如果访问不成功,就需要关注,component 的引入,可能是自己的页面名称没有和它匹配


这里和我们在处理数据的时候,对于component 里面的路径有关的

好了,以上就是我的全部 实现过程,也走了很多弯路,尤其是那个router.options.routers这个打印不出来我的动态路由,我一度迷茫,说addRoute 咋没有效果 失效了呢,惆怅是不是添加进入的时机不对,救命!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。