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. rest api_REST API
  2. 高效开发:IntelliJ IDEA天天用,这些Debug技巧你都知道?
  3. MatLab画图总结
  4. 复旦邱锡鹏超全NLP预训练模型综述论文:两张图带你梳理完整脉络
  5. 几种常见自动化测试框架
  6. 2016-03-09c中指针与数组学习记录
  7. JS Math对象中一些小技巧
  8. Message-Digest Algorithm 5
  9. 使用C语言----修改密码
  10. 数据结构专题(二):2.3链表插入元素,尾插法
  11. 深度学习自学(九):Alexnet解读
  12. python中判断对象是否可迭代
  13. 惊!微信可以转发语音了?!
  14. AI教程视频《AI illustrator入门到精通》零基础自学教程教学
  15. C语言:数组数据移动
  16. 靶机渗透练习58-digitalworld.local:VENGEANCE
  17. 江苏大学 操作系统 知识点提纲 期末考试/考研 复习
  18. python tkinter怎么读_Tkinter是什么意思
  19. 一看就懂的贪吃蛇游戏(c++实现)
  20. 8421码到5421码的转换_如何实现用283加法器实现8421码到5421码的转换

热门文章

  1. 判断小球-第14届蓝桥杯STEMA测评Scratch真题精选
  2. linux jedi-vim安装,SpaceVim安装与环境配置
  3. 小米手机的售后让我伤心让我恨!!
  4. linux系统重置mysql_Linux下重置MySQL密码
  5. 动画学习之WIFI图形绘制
  6. Python自动化办公,深度优先搜索文件夹并移动全部doc文件(深度优先算法)以及(文件、文件夹的移动、复制、删除、重命名)
  7. 72 R baging和boosting比较
  8. 14、JSON、拷贝
  9. Vitu全新社区来了
  10. Creo5.0关闭默认内置浏览器