一般来说,vue项目实现动态路由的方式大体可分为两种:

  1. 前端把路由写好,登录的时候根据用户的角色权限来动态展示路由,(前端控制路由)
  2. 后台接口提供当前用户对应权限的路由表,前端通过调接口拿到后处理(后端处理路由)

一、场景:

不同权限的用户登录后显示不同的菜单,每次请求接口,前端需要在header中携带用户的token,这样后端才能验证用户是否有权限执行该操作。

  • 登录:当用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token,拿到token之后,将这个token存储到cookie中,保证刷新页面后能记住用户登录状态,在全局钩子router.beforeEach中拦截路由中,判断是否已获得token,在获得token之后根据token拉取用户的基本信息。
  • 权限验证:通过token获取用户对应的 role,动态根据用户的 role 算出其对应有权限的路由,通过 router.addRoutes 动态挂载路由。

二、思路

① 在vue-router对象中首先初始化公共路由,比如(首页,404,login)等。

② 用户登陆成功后,根据用户的角色信息,获取对应权限菜单信息menuList,并将后台返回的menuList转换成我们需要的router数据结构。

③ 通过**router.addRouter(routes)**方法 添加并实现。

二、实现
关键点是router.addRoute方法

(1)初始化公共路由

//只显示主要代码
export const routes= [{ path: '/login', component: () => import('@/views/login/index'), hidden: true },{ path: '/404', component: () => import('@/views/404'), hidden: true }
]
export default new Router({scrollBehavior: () => ({ y: 0 }),routes: routes
})

(2) 登陆成功后,获取菜单信息 menuList,并转换成router数组的结构

router.beforeEach((to, from, next) => {NProgress.start()//进度条包 npm安装if (getToken()) {/*有 token,已经登录成功*/if (to.path === '/login') {next({ path: '/' })NProgress.done()} else {if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息store.dispatch('GetInfo').then(res => { // 拉取user_infoconst roles = res.rolesstore.dispatch("GetMenu").then(data => {initMenu(router, data);});next()}).catch((err) => {store.dispatch('FedLogOut').then(() => {Message.error(err || 'Verification failed, please login again')next({ path: '/' })})})} else {next()}}} else {/* 无 token*/if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入next()} else {next('/login') // 否则全部重定向到登录页NProgress.done()}}
})
router.afterEach(() => {NProgress.done()
})

(3)动态加载路由

import store from '../store'
export const initMenu = (router, menu) => {if (menu.length === 0) {return}let menus = formatRoutes(menu);let unfound = { path: '*', redirect: '/404', hidden: true }menus.push(unfound) //404组件最后添加router.addRoutes(menus)store.commit('ADD_ROUTERS',menus)
}
export const formatRoutes = (aMenu) => {const aRouter = []aMenu.forEach(oMenu => {const {path,component,name,icon,childrens} = oMenuif (!validatenull(component)) {let filePath;const oRouter = {path: path,component(resolve) {let componentPath = ''if (component === 'Layout') {require(['../views/layout/Layout'], resolve)return} else {componentPath = component}require([`../${componentPath}.vue`], resolve)},name: name,icon: icon,children: validatenull(childrens) ? [] : formatRoutes(childrens)}aRouter.push(oRouter)}})return aRouter
}

(4)渲染菜单

<template><el-scrollbar wrapClass="scrollbar-wrapper"><el-menumode="vertical":show-timeout="200":default-active="$route.path":collapse="isCollapse"background-color="#304156"text-color="#bfcbd9"active-text-color="#409EFF"><sidebar-item v-for="route in permission_routers" :key="route.name" :item="route" :base-path="route.path"></sidebar-item></el-menu></el-scrollbar>
</template><script>
import { mapGetters } from 'vuex'
import SidebarItem from './SidebarItem'
import { validatenull } from "@/utils/validate";
import { initMenu } from "@/utils/util";export default {components: { SidebarItem },created() {},computed: {...mapGetters(['permission_routers','sidebar','addRouters']),isCollapse() {return !this.sidebar.opened}}
}
</script>

(5)防坑

点击刷新的时候页面空白 控制台也不报错?

点击刷新,vue-router会重新初始化,那么我们之前的动态addRoute就不存在了,此时访问一个不存在的页面,所以我们的sidebar组件也就不会被访问,那么也无法获取菜单信息,就导致页面空白。所以我们需要把加载菜单信息这一步放在router的全局守卫beforeEach中就可以了。

export const initMenu = (router, menu) => {if (menu.length === 0) {return}let menus = formatRoutes(menu);// 最后添加let unfound = { path: '*', redirect: '/404', hidden: true }menus.push(unfound)router.addRoutes(menus)store.commit('ADD_ROUTERS',menus)
}
//404组件一定要放在动态路由组件的最后,不然你刷新动态加载的页面,会跳转到404页面的

vue 项目如何实现动态加载路由?相关推荐

  1. vue动态加载路由的实现

    动态加载路由的实现 vue后台管理之动态加载路由 vue路由动态加载

  2. vue系统权限(动态加载路由方式)

    目录 1.注册vue-router 2.声明 默认路由 和权限路由 3.用vuex实现全局登录.退出登录等方法 4.用vuex模块单独写权限路由的判断 5.监听路由跳转实现动态加载权限菜单 需要用到动 ...

  3. nodejs动态加载路由

    Nodejs动态加载路由,Nodejs遍历目录,Nodejs路由工具 工具来源: Nodejs需要手动加载路由文件,如果一个个添加,项目逐渐扩大,比较麻烦. 尤其在项目route目录下,增加模块文件夹 ...

  4. vue+elementui 中src动态加载图片的时候不起作用

    vue+elementui 中src动态加载图片的时候不起作用 代码如下: <el-table-column align="center" label="宠物图片& ...

  5. reactjs通过lazy函数配合import函数动态加载路由组件

    路由组件的lazyLoad //1.通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包const Login = lazy(()=>i ...

  6. vue 根据组件地址动态加载异步组件

    要求:根据列表中配置的组件地址,动态加载组件(webpart) vue 根据组件地址动态加载异步组件 目录结构 index.html components/component1 components/ ...

  7. vue 实现tab切换动态加载不同的组件

    vue 实现tab切换动态加载不同的组件 使用vue中的is特性来加载不同的组件.具体看如下代码:这个功能对于vue比较复杂的页面可以使用上,可以把一个页面的功能拆分出来,使代码更简单.使用方式具体看 ...

  8. Vue下拉框动态加载数据

    Vue下拉框动态加载数据 <template><a-select v-model="model.type" show-search placeholder=&qu ...

  9. vue项目中 img标签加载失败方法,onerror事件的两种方法

    vue项目中 img标签加载失败方法 ?css 第一种方法 第二种方法 本人写的第一篇文章,希望对你有帮助 第一种方法 < img src="123" :οnerrοr=&q ...

最新文章

  1. 查杀DeDe数据库后门 网站安全狗DeDe专杀工具
  2. python创建一个有序链表_算法2-2:生成递增有序链表+两个链表合并
  3. Alphabet以3.8亿美元收购董事格林创业公司Bebop
  4. Net 5.0 快速开发框架 YC.Boilerplate--框架介绍
  5. iphone储存空间系统怎么清理_如何清理iPhone的缓存,释放更多存储空间,这些方法你知道吗...
  6. share——Alpha版(内部测试版)发布
  7. mamp安装php扩展,向MAMP添加GMP PHP扩展
  8. Python自动化课之Day3篇
  9. 来来,一起设计一个简单的活动发布系统
  10. python gdbm_linux下python安装
  11. JavaScript中atEnd函数
  12. testbed代码审查信息提取
  13. 什么是噪声,白噪声,加性噪声,乘性噪声
  14. 【评测】常用免疫细胞培养基
  15. 使用iperf测试网速
  16. 攻防世界 Pwn Mary_Morton
  17. 大二暑假java培训第七天
  18. Jenkins打包部署项目到Windows或Linux运行
  19. 12306验证图片集合。
  20. 【JAVA】Java8对时间的一些常用操作记录。例如:LocalDateTime、ZoneId等。

热门文章

  1. 设计模式(C++实现)(二十三)——享元模式
  2. 文件隐藏软件,6种保护文件方式,实现隐藏并锁定
  3. 多张png合成为nii.gz
  4. 2023年图情档研究生入学考试专业课真题回忆版
  5. 【线性模型引论】王松桂著 课后习题3.9参考答案
  6. Windows Connectify使自己笔记本变无线路由器
  7. 如何让ps选框工具显示宽高,如何恢复原始ps界面
  8. 支付宝认证的作用是什么?考试方向有哪些?
  9. cfc 教程_Google CFC
  10. 解决报错OSError: dlopen(../anaconda/envs/python3/lib/python3.6/site-packages/lightgbm/lib_lightgbm.so)