1. 需求描述

最近开发的一个项目,涉及到这样一个需求:随着项目的不断推进,后台管理功能逐渐增多,与此同时,静态路由表也逐渐扩大,需要把静态路由方式转换为动态路由方式。要完成这样一个转换,有几个技术要点需要解决,其中一个就是前端的实现方式。那么,前端如何实现呢?

2. 实现

Vue动态路由的前端实现,网上有不少参考资料。但大多存在代码冗余,思路模糊不清的情况。现在整理一下思路。当前端发送登录请求login向后台请求数据后,后台会返回一个user对象至前端,前端把该对象保存至vuex中,同时,保存user中的token对象至vuex中。在vuex模块对应的store文件家中,Vue2对应两个文件:getters和index。
getters 文件源码

let getters = {user: state => state.user,token: state => state.token,routes: state => state.routes
}
export default getters

index文件源码

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import persistedState from 'vuex-persistedstate'Vue.use(Vuex)const state = {token: '',user: '',routes: []
}
const mutations = {setToken (state, token) {state.token = token},setUser (state, user) {state.user = user},setRouter (state, routes) {state.routes = routes},clear (state) {state.token = ''state.user = ''state.routes = []}
}const store = new Vuex.Store({state,getters,mutations,plugins: [persistedState({ storage: window.sessionStorage })]
})export default store

注意: 其中persistedState 为持久化插件,使得刷新的时候,保存vuex中的数据不丢失,从而回到当前页面,而不至于刷新后丢失数据后回到登录页。

回到刚才的话题,在前端登录请求中,登录认证成功后,在回调函数中,会获取到user对象。该对象中保存有token信息,同时,也保存有treeMenu信息。

如何在静态路由和动态路由之间比较自由的切换,显然,修改的地方越少越好。
由于router文件夹中的静态路由涉及到权限敏感的路由数据会被注释掉,并放入后台数据库,此为需要修改的第一个地方。即 注释和反注释。
需要特别说明的是,在登录方法中,并不需要修改代码。
需要修改代码的第二个地方,就是路由守卫的文件里面。
源码如下所示

import router from './router'
import store from './store'
import {deepClone} from './utils'
// 获取组件的方法
let _import = file => require('@/views' + file + '.vue').default
// 页面全局路由列表
let getRouter = []
// 默认静态路由的长度
let staticRouterLength = 3
let staticRouter = []router.beforeEach((to, from, next) => {// 判断该路由是否需要登录权限if (to.path === '/' || to.path === '/app2' || to.path === '/login') {next()} else {if (!store.state.token) { // 未登录next({path: '/login'// 将跳转的路由path作为参数,登录成功后跳转到该路由。// query: {redirect: to.fullPath}})} else {// 已登录// next()// ------------切换为动态路由----------------// 已登录的情况下,从vuex中获取用户菜单列表,进行组件的初始化。// 静态路由为登录等基本的路由。if (store.state.routes.length === 0 || router.options.routes.length === staticRouterLength) {if (router.options.routes.length === staticRouterLength) {// 静态路由的情况下,把静态路由信息存入静态变量staticRouter = deepClone(router.options.routes)}// 从vuex的user对象中获取菜单树后台数据let treeMenu = deepClone(store.state.user['treeMenu'])// 通过页面全局变量,进一步加载getRoutergetRouter = filterAsyncRouter(treeMenu)// 把该加载的全局变量存入vuex中store.commit('setRouter', getRouter)// 跳转到异步加载路由nextAsyncRouter(to, next)} else {next()}}}
})function nextAsyncRouter (to, next) {// 更新路由数据 : 静态路由数据 + 动态路由数据router.options.routes = deepClone(staticRouter).concat(getRouter)router.addRoutes(getRouter)// 跳转到目标位置,循环加载,直到组件初始化好。next(to, {replace: true})
}/*** 递归加载路由组件* @param asyncRouterMap 可获取的路由列表* @returns {*}*/
function filterAsyncRouter (asyncRouterMap) {const accessedRouters = asyncRouterMap.filter(route => {if (route.component) {route.component = _import(route.component)if (route.children && route.children.length) {// 递归调用route.children = filterAsyncRouter(route.children)}}return true})return accessedRouters
}

注意:上述代码中,静态路由和动态路由的切换很简单,只需要else中,已登录的情况下,静态路由变为next(),把其他代码注释即可。
上述代码,实现了静态路由表和动态路由表的拼接,即基本的一些功能可以放在前端静态路由中,涉及到用户角色权限的路由部分,放在数据库中,根据用户的权限,向数据库请求对应的动态菜单返回加载即可。
干货收集分享:
下面,附上之前收集整理并若干修改之后的工具代码的两个方法。

/*** 深度拷贝*/
export function deepClone (obj) {/*** 加入空值判断*/if (obj === null) {return null}let newObj = obj instanceof Array ? [] : {}for (let k in obj) {newObj[k] = typeof obj[k] === 'object' ? deepClone(obj[k]) : obj[k]}return newObj
}/*** 判断对象是否是数组*/
export function isArrayFn (value) {// 首先判断浏览器是否支持Array.isArray这个方法if (typeof Array.isArray === 'function') {return Array.isArray(value)} else {return Object.prototype.toString.call(value) === '[object Array]'// return obj.__proto__ === Array.prototype;}
}

3. 结语

Vue动态路由涉及到的知识从动态组件的加载,到后台,再到前端,每一个地方都有若干需要注意的细节要点,可以说,实现这个功能,参考了不少网络资料,从中获益匪浅。在Vue动态路由实现的参考文章中,差不多都会在路由守卫中重新发送请求,获取treeMenu数据,其实,这个地方是没有必要再次发送请求的,因为在login方法中,已经把user对象存入vuex中,该user对象中,已经包含了完整的treeMenu信息。 只是在动态加载组件的时候,因为是按需异步加载,如果加载没有完成,需要从新跳转到目标位置,循环加载,直到组件初始化好(参考上面源码注释即可理解)。

4. 参考资源

(1)vue 实现动态路由
(2)关于vue-router动态添加路由$router.options不更新的解决办法
(3)js如何判断一个对象是数组(函数)

Vue动态路由的前端实现相关推荐

  1. ant design pro vue 动态路由 流程详解

    ant design pro vue 动态路由 流程详解 前言 流程图 流程1 src/permission.js 流程2 src/store/modules/user.js 流程3 src/perm ...

  2. Vue动态路由传参和监听路由

    Vue动态路由传参 query传参 params传参 //定义Detail路由 {path: '/detail/:id',name: 'Detail'component: () => impor ...

  3. Vue 动态路由的实现(后台传递路由,前端拿到并生成侧边栏),其实就是路由在后台配置 前端请求接口后 生成路由表

    最近刚结束一个项目,然后再客户的百般刁难下又增加了项目新需求: 后台传来当前用户对应权限的路由表,前端通过调接口拿到后处理(后端处理路由) vue项目实现动态路由的方式大体可分为两种: 1.第一种就是 ...

  4. Vue 动态路由的实现(后台传递路由,前端拿到并生成侧边栏)

    今天我们来讲讲用后台传递路由表实现动态路由的思路,因为公司的项目里路有部分用到了vuex,我就把路由部分脱离vuex整理了出来,让大家有个启发,并不是绝对的解决方案,只是思路 github:https ...

  5. Vue 动态路由的实现以及 Springsecurity 按钮级别的权限控制

    思路: 动态路由实现:在导航守卫中判断用户是否有用户信息,通过调用接口,拿到后台根据用户角色生成的菜单树,格式化菜单树结构信息并递归生成层级路由表并使用Vuex保存,通过 router.addRout ...

  6. seo vue 动态路由_基于Vue SEO的四种方案

    前言:众所周知,Vue SPA单页面应用对SEO不友好,当然也有相应的解决方案,下面列出几种最近研究和使用过的SEO方案,SSR和静态化基于Nuxt.js来说. 关于服务器渲染:,对Vue版本有要求, ...

  7. vue动态路由添加,vue-router的addRoute方法实现权限控制,添加根路由和子路由

    addRoute 路由分为静态路由和动态路由 静态路由和动态路由的优缺点 动态路由实现思路: 动态路由遇到的问题与解决方式 动态添加子路由 路由分为静态路由和动态路由 静态路由和动态路由的优缺点 1. ...

  8. vue动态路由权限管理

    通常我们在vue项目中都是前端配置好路由的,但在一些项目中我们可能会遇到权限控制,这样我们就涉及到动态路由的设置了. 动态路由设置一般有两种: (1).简单的角色路由设置:比如只涉及到管理员和普通用户 ...

  9. vue动态路由配置, 通过路由区分模块化打包配置

    import Vue from 'vue'; import Router from 'vue-router'; import config from '@/config';Vue.use(Router ...

最新文章

  1. bms_output.put_line使用方法
  2. spring aop 必须的包 及里面用到的东西_Spring 原理初探——IoC、AOP
  3. python并发编程之semaphore(信号量)_浅谈Python并发编程之进程(守护进程、锁、信号量)...
  4. 哈佛大学刘小乐教授讲授的计算生物学和生物信息学导论 (2020 视频+资料)
  5. 安装的mysql密码忘了_mysql8安装成功后忘记密码
  6. python机器学习库sklearn——决策树
  7. 了解Java密码扩展的基础
  8. 基于.net开发chrome核心浏览器【三】
  9. oracle begin 后声明,Oracle BEGIN END 详细用法
  10. 商业力:开发者一站式服务
  11. 【开箱即用】HTML5教程
  12. 【内推】阿里云 云原生团队 2022 届秋招
  13. 中望3D 2021 插入基准面 - 三点法
  14. 同时使用两片I2C同型号设备时地址怎样设置 (如何更改器件地址)
  15. Java使用freemarker生成word文档并转pdf文档
  16. 专业方向系列-01-大数据与故障诊断概述
  17. Mozilla发布最大的人类语音数据集(Common Voice)
  18. 巨震行情下反映出的人性
  19. 输出100以内含7或7的倍数
  20. java中shot占几个字节_Java 占用字节数

热门文章

  1. Docker镜像文件介绍启动tomcat
  2. 计算机如何解决卡顿问题,电脑越来越卡如何解决 六种应对方法轻松解决问题...
  3. 828. 统计子串中的唯一字符
  4. 增强精英保留策略的遗传算法SEGA
  5. 用vert.x与echarts开发实时环境监控
  6. gt和htd什么区别_同步带htd-3m和s3m区别是什么
  7. 重量转换之克、两、斤
  8. jetson tx2 安装cuda 10.2或者cuda 9全过程
  9. 《长安十二时辰》愿你看尽世间百态,心中仍有热血
  10. SpringBoot之整合Swagger(页面无法显示)