前端的路由从后台获取,包括权限;

大体步骤包括:路由拦截(钩子函数)---->后台获取路由数据 ----> 保存到本地或vuex中.

在router-->index.js中:

 router.beforeEach((to, from, next) => { //拦截处一定要else{}
// 加载动态菜单和路由
if (to.path === '/') {
addDynamicMenuAndRoutes(to, from)
console.log(router.options.routes);
next()
} else {
if (store.state.menu.navTree) {
addDynamicMenuAndRoutes(to, from)
}
next()
}
})

一个Tip,钩子函数一定要记得else{},就这个小问题找了半天,各种排除。。。

我这里没有登录验证,所以通过path来判断是否加载动态路由;

下面的判断是由于vuex在F5刷新时会清空,所以通过里面是否有vuex里的某个状态来判断是否要再次加载路由;一般用登录的token判断;

下面是加载动态路由的关键函数:

 /**
* 加载动态菜单和路由
*/
function addDynamicMenuAndRoutes(to, from) {
// 处理IFrame嵌套页面
handleIFrameUrl(to.path)
api.menu.findMenuTree()
.then(res => {
// 添加动态路由
console.log(res.data)
let dynamicRoutes = addDynamicRoutes(res.data)
// 处理静态组件绑定路由
handleStaticComponent(router, dynamicRoutes)
router.addRoutes(router.options.routes)
console.log(router.options.routes)
// 保存加载状态
store.commit('menuRouteLoaded', true)
// 保存菜单树
store.commit('setNavTree', res.data)
}).then(res => {
// api.user.findPermissions({ 'name': userName }).then(res => {
// // 保存用户权限标识集合
// store.commit('setPerms', res.data)
// })
})
.catch(function(res) {})
}

添加动态路由:

 /**
* 添加动态(菜单)路由
* @param {*} menuList 菜单列表
* @param {*} routes 递归创建的动态(菜单)路由
*/
function addDynamicRoutes(menuList = [], routes = []) {
var temp = []
for (var i = 0; i < menuList.length; i++) {
if (menuList[i].children && menuList[i].children.length >= 1) {
temp = temp.concat(menuList[i].children)
} else if (menuList[i].url && /\S/.test(menuList[i].url)) {
//menuList[i].url = menuList[i].url.replace(/^\//, '')
menuList[i].url = menuList[i].url.substring(1);
try {
// 根据菜单URL动态加载vue组件,这里要求vue组件须按照url路径存储
// 如url="sys/user",则组件路径应是"@/views/sys/user.vue",否则组件加载不到
let array = menuList[i].url.split('/')
let url = ''
for (let i = 0; i < array.length; i++) {
url += array[i].substring(0, 1).toUpperCase() + array[i].substring(1) + '/'
}
url = url.substring(0, url.length - 1)
var route = {
path: menuList[i].url,
component: resolve => require([`@/views/${url}`], resolve),
name: menuList[i].name,
meta: {
icon: menuList[i].icon,
index: menuList[i].id
}
}
} catch (e) {}
// }
routes.push(route)
}
}
if (temp.length >= 1) {
addDynamicRoutes(temp, routes)
} else {
// console.log('动态路由加载...')
// console.log('动态路由加载完成.')
}
return routes
}

模拟后台的路由数据:

  "data": [{
"id": 1,
"createBy": null,
"createTime": null,
"lastUpdateBy": null,
"lastUpdateTime": null,
"parentId": 0,
"name": "系统配置",
"url": null,
"perms": null,
"type": 0,
"icon": "el-icon-setting",
"orderNum": 0,
"delFlag": 0,
"parentName": null,
"level": 0,
"children": [{
"id": 2,
"createBy": null,
"createTime": null,
"lastUpdateBy": null,
"lastUpdateTime": null,
"parentId": 1,
"name": "角色配置",
"url": "/sys/user",
"perms": null,
"type": 1,
"icon": "el-icon-service",
"orderNum": 1,
"delFlag": 0,
"parentName": "系统配置",
"level": 1,
"children": []
}, {
"id": 3,
"createBy": null,
"createTime": null,
"lastUpdateBy": null,
"lastUpdateTime": null,
"parentId": 1,
"name": "业务配置",
"url": "/sys/dept",
"perms": null,
"type": 1,
"icon": "el-icon-news",
"orderNum": 2,
"delFlag": 0,
"parentName": "系统配置",
"level": 1,
"children": []
}, {
"id": 4,
"createBy": null,
"createTime": null,
"lastUpdateBy": null,
"lastUpdateTime": null,
"parentId": 1,
"name": "权限配置",
"url": "/sys/role",
"perms": null,
"type": 1,
"icon": "el-icon-view",
"orderNum": 4,
"delFlag": 0,
"parentName": "系统配置",
"level": 1,
"children": []
}, {
"id": 5,
"createBy": null,
"createTime": null,
"lastUpdateBy": null,
"lastUpdateTime": null,
"parentId": 1,
"name": "流程控制",
"url": "/sys/menu",
"perms": null,
"type": 1,
"icon": "el-icon-menu",
"orderNum": 5,
"delFlag": 0,
"parentName": "系统配置",
"level": 1,
"children": []
},
{
"id": 7,
"createBy": null,
"createTime": null,
"lastUpdateBy": null,
"lastUpdateTime": null,
"parentId": 1,
"name": "大数据",
"url": "/sys/dict",
"perms": null,
"type": 1,
"icon": "el-icon-edit-outline",
"orderNum": 7,
"delFlag": 0,
"parentName": "系统配置",
"level": 1,
"children": []
},
{
"id": 8,
"createBy": null,
"createTime": null,
"lastUpdateBy": null,
"lastUpdateTime": null,
"lastUpdateTime": "2018-09-23T11:32:28.000+0000",
"parentId": 1,
"name": "数据过滤",
"url": "/sys/log",
"perms": "sys:log:view",
"type": 1,
"icon": "el-icon-info",
"orderNum": 8,
"delFlag": 0,
"parentName": "系统配置",
"level": 1,
"children": []
}, {
"id": 9,
"createBy": null,
"createTime": null,
"lastUpdateBy": "admin",
"lastUpdateTime": "2018-09-23T11:32:28.000+0000",
"parentId": 1,
"name": "系统维护",
"url": "/sys/dispose",
"perms": "sys:dispose:view",
"type": 1,
"icon": "el-icon-info",
"orderNum": 9,
"delFlag": 0,
"parentName": "系统配置",
"level": 1,
"children": []
}
]
}
]

本文主要参考 朝雨忆轻尘,感谢大佬的详细介绍。

另附出处: https://www.cnblogs.com/xifengxiaoma/

vue管理平台的动态路由(后台传递路由,前端拿到并生成侧边栏)的更多相关文章

  1. vue 中下拉select怎样给后台传递用户选择的物品id

    在泰康保险公众号项目中有个问题是用户选择select中的option,要把对应的id给后台以便后台工作作出相应的效果,我是这样的 <select v-model="selectcomu ...

  2. 基于SpringBoot+SSM实现的Dota2资料库智能管理平台

    Dota2资料库智能管理平台的设计与实现 摘    要 当今社会,游戏产业蓬勃发展,如PC端的绝地求生.坦克世界.英雄联盟,再到移动端的王者荣耀.荒野行动的火爆.都离不开科学的游戏管理系统,游戏管理系 ...

  3. Vue之单文件组件的数据传递,axios请求数据及路由router

    1.传递数据 例如,我们希望把父组件的数据传递给子组件. 可以通过props属性来进行传递. 传递数据三个步骤: 步骤1:在父组件中,调用子组件的组名处,使用属性值的方式往下传递数据 <Menu ...

  4. 关于vue项目管理项目的架构管理平台

    关于vue项目管理项目的架构管理平台 https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/faq 31.4k 次浏览 完整项目地址: ...

  5. vue2.0+elementUI构建单页面后台管理平台

    git:https://github.com/reg21st/vue2-management-platform 访问:https://reg21st.github.io/vue2-management ...

  6. 【vue】iView-admin2.0动态菜单路由

    vue项目实现动态路由有俩种方式 一.前端在routers中写好--所有--路由表 <前端控制路由>,登录时根据用户的角色权限来动态的显示菜单路由 二.前端通过调用接口请求拿到当前用户-- ...

  7. Vue | 自定义指令和动态路由实现权限控制

    功能概述: 根据后端返回接口,实现路由动态显示 实现按钮(HTML元素)级别权限控制 涉及知识点: 路由守卫 Vuex使用 Vue自定义指令 导航守卫 前端工程采用Github开源项目Vue-elem ...

  8. vue-element-admin改造接入后台,搭建有来商城youlai-mall后台前端管理平台

    一. 前言 本篇基于有来商城youlai-mall微服务项目,搭建后台前端管理平台,技术选型希望通过本篇文章你可以,技术解决方案选择了vue-element-admin.希望通过本篇文章你可以vue- ...

  9. vue-element-admin改造接入后台,搭建有来商城youlai-mall前后端分离管理平台

    一. 前言 本篇基于有来商城youlai-mall微服务项目搭建的后台前端管理平台,技术选型Vue+Element-UI实现前后端分离,解决方案选型vue-element-admin.希望通过本篇你可 ...

随机推荐

  1. python多线程交替打印abc以及线程池进程池的相关概念

    import threading import sys import time def showa(): while True: lockc.acquire() #获取对方的锁,释放自己的锁 prin ...

  2. AI能帮我们造出一个无肉的世界吗?

    AI听起来很遥远,其实已经渗透到我们的日常工作和生活中.在不远的未来,互联网.大数据.硬件的发展和软件的优化,乃至全社会的参与,人工智能将真正从实验室走进生活,它将成为改变我们生活的一部分.我们吃的肉 ...

  3. Hihocoder1456 Rikka with Lattice

    众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:勇太有一个$n times m$的点阵,他想要从这$n times m$个点中选出三个点 ${A,B,C}$,满足 ...

  4. Android 添加framework资源包

    为Android系统添加一个新的资源包 概述 传统的Android系统只有一个framework-res.apk资源包,第三方厂商在进行rom定制时会直接修改framework res资源,达到适配目 ...

  5. CSS——NO.3(CSS选择器)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  6. 做直播能有多赚钱,Python告诉你

    前面我们介绍了APP爬虫环境的搭建和mitmproxy工具的简单使用,这次我们要来一个简单的APP爬虫,尝试一下APP爬虫的简单实用,顺便让我们看看喜马拉雅上的主播到底有多赚钱. APP爬虫一般分为两 ...

  7. Java程序员考研失败后的面试经历,oppo、VIVO、等面经

      温馨提示:有些可能会遗漏个别问题,都是最近一周的面试,有点忘了. 浪潮(一面挂) 你是网络工程的?对网络很了解? 解释一下什么是广播域 怎么划分子网 说一下CSS的几种分类器 数据库中有哪些聚集函 ...

  8. 沙雕与大婶 | Mock调你的外部依赖吧

    故事背景: 沙雕在公司负责API项目的开发,很认真负责,经常加班加点赶进度,却常常被老板吐槽说他开发效率太低,他自己也很委屈,因为他所负责的项目常常依赖大量外部系统,他只好等对方开发完才一个个对接,开 ...

  9. Spring 事务传播机制和数据库的事务隔离级别

    Propagation(事务传播属性) 类别 传播类型 说明 支持当前事务 REQUIRED 如果当前没有事务,就新建一个事务.@Transaction的默认选择 支持当前事务 SUPPORTS 就以 ...

  10. &#160;前端面试题目总结1

    数据类型 js中的数据类型有两类:值类型和引用类型 值类型:number.string.boolean.Symbol.undefined 引用类型:null.数组.对象 使用typeof能用来干什么 ...