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

大体步骤包括:路由拦截(钩子函数)---->后台获取路由数据 ----> 保存到本地或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. deeplearning.ai 神经网络和深度学习 week2 神经网络基础

    1. Logistic回归是用于二分分类的算法. 对于m个样本的训练集,我们可能会习惯于使用for循环一个个处理,但在机器学习中,是把每一个样本写成一个列向量x,然后把m个列向量拼成一个矩阵X.这个矩 ...

  2. vue-cli3初始化项目

    1 npm install -g @vue/cli 创建配置 创建 1 vue create vue-app 选择配置 1234 ? Please pick a preset: (Use arrow ...

  3. Protein interaction|insight QUANTA|SYBYL COMPOSER|MODELLER|SWISS_MODEL|WHAT IF|3D-JIGSAW|CPH-ModelGPCRs|Membrane protein|

    生命组学 蛋白质之间的互作可以有以下应用: Eg:改变蛋白质基因,从而组改变结构,削弱蛋白质之间的相互作用. Eg:数据模拟出蛋白质的靶点,即结合腔,将此数据存入结合化合物的dataset,用于制药 ...

  4. LINQ之路 7:子查询、创建策略和数据转换(要点笔记)

    匿名类型 上面我们自己定义了类型TempProjectionItem来存放查询的结果.通过使用匿名类型,我们可以省去这种中间类型的定义,而由编译器来帮我们完成: select item.Origina ...

  5. Android开发之《Module相互引用,NDK不能正常Debug》

    解决Android Studio不能进入调试模式问题 Android Studio 2.2.3 native debug 无法调试?:https://www.zhihu.com/question/54 ...

  6. Scarpy框架安装教程

    在一切之前,建议升级pip,如果版本太低,安装会失败 升级pip命令: python -m pip install --upgrade pip 如果上面的命令不能用,用下面这个 easy_instal ...

  7. Python Web 基础向(四) 浅谈数据层

    数据层一般会给人带来一些困扰,在于其定位不准确.聚合Model的工作也可以放在逻辑层做,但会导致逻辑层变重,经常出现大段晦涩代码.因此我的建议是保留Model聚合层,尽管会导致工作量的略微增加,但却可 ...

  8. xstream的介绍及用法

    使用xstream工具包导入xpp3_min-1.1.4c和xstream-1.4.9特点:代码简洁,超级方便,可以自己定义xml格式(适合做文件传输)属性特点:1. xStream.alias(&q ...

  9. JMeter之BeanShell断言---equals使用

    判断变量是否为root if(!"${User}".equals("root")){ Failure=true; FailureMessage="ER ...

  10. JavaScript值类型和引用类型有哪些

    JavaScript值类型和引用类型有哪些 (1)值类型:数值.布尔值.null.undefined. (2)引用类型:对象.数组.函数.