Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!


2013年7月28日,尤雨溪第一次在 GItHub 上为 Vue.js 提交代码;2015年10月26日,Vue.js 1.0.0版本发布;2016年10月1日,Vue.js 2.0发布。

最早的 Vue.js 只做视图层,没有路由, 没有状态管理,也没有官方的构建工具,只有一个库,放到网页里就可以直接用了。

后来,Vue.js 慢慢开始加入了一些官方的辅助工具,比如路由(Router)、状态管理方案(Vuex)和构建工具(Vue-cli)等。此时,Vue.js 的定位是:The Progressive Framework。翻译成中文,就是渐进式框架。

Vue.js2.0 引入了很多特性,比如虚拟 DOM,支持 JSX 和 TypeScript,支持流式服务端渲染,提供了跨平台的能力等。Vue.js 在国内的用户有阿里巴巴、百度、腾讯、新浪、网易、滴滴出行、360、美团等等。

Vue 已是一名前端工程师必备的技能,现在就让我们开始深入学习 Vue.js 内部的核心技术原理吧!


什么是权限控制

在我们开发项目的时候,尤其是管理后台项目中,都会遇到根据用户角色来进行相关功能的展示和隐藏。比如超级管理员可以查看所有的模块,普通用户只能看一部分模块,而且还可能会有一个菜单管理模块,可以对不同用户的角色进行相关配置。根据系统中各个角色进行相关的访问权限限制,就是我们这里说的权限控制。


什么是addRoute()

我们先看一下官方是怎么定义的:

添加一条新路由规则。如果该路由规则有name,并且已经存在一个与之相同的名字,则会覆盖它。

函数签名:

addRoute(route:RouteConfig):() => void

其中RouteConfig接口定义如下:

interface RouteConfig = {path: string,component?: Component,name?: string, // 命名路由components?: { [name: string]: Component }, // 命名视图组件redirect?: string | Location | Function,props?: boolean | Object | Function,alias?: string | Array<string>,children?: Array<RouteConfig>, // 嵌套路由beforeEnter?: (to: Route, from: Route, next: Function) => void,meta?: any,// 2.6.0+caseSensitive?: boolean, // 匹配规则是否大小写敏感?(默认值:false)pathToRegexpOptions?: Object // 编译正则的选项
}

该函数执行后产生的结果就是,会将参数route添加我们系统的路由表中。

比如下面这种:

const constantRoutes = [{path: "/login",name: "login",component: () => import("@/views/login")},{path: "/home",component: () => import("@/views/home"),redirect: "/home",name: "首页",meta: { title: "首页", icon: "el-icon-s-help" }}
];const createRouter = () =>new Router({routes: constantRoutes});// 此时,当前路由表只有两个路由
// 下面通过addRoute方法来添加路由
const route = createRouter()  // 拿到路由对象
route.addRoute({{path: "/hello",component: () => import("@/views/hello"),redirect: "/hello",name: "你好",meta: { title: "你好", icon: "el-icon-s-help" }}
})
// 现在,路由表中就有三个路由了

如何进行权限控制

一般我们进行权限控制的话,有两种方案,一种是前端也保存一套路由表,一种是前端不保存路由表,路由表信息全部由后端返回。

  • 第一种:前端保存一套路由表

我们先看第一种的实现思路:

  1. 前端保存全部页面的路由信息,并且在每个路由信息中保存当前路由对应的权限关键字。

  2. 每次用户登录成功的时候,后台返回当前用户对应的权限关键字

  3. 前端根据后台返回的权限关键字,遍历自己前端保存的路由表

  4. 将符合用户权限的路由,通过addRoute()动态添加到路由表中

具体实现如下:

  1. 第一步,在前端保存一套路由表

// route.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)const constantRoutes = [{path: "/login",name: "login",component: () => import("@/views/login")},{path: "/home",component: () => import("@/views/home"),redirect: "/home",name: "首页",meta: { title: "首页", icon: "el-icon-s-help" }}
];  // 常用路由表export const asyncRoute = [{path: "/asyncRoute1",name: "asyncRoute1",component: () => import("@/views/asyncRoute1"),meta: { title: "动态路由1", icon: "el-icon-s-help",roles: ['admin', 'ordinaryUsers']  // 当前路由对应的权限关键字,超级管理员和普通用户}},{path: "/asyncRoute2",component: () => import("@/views/asyncRoute2"),name: "asyncRoute2",meta: { title: "动态路由2", icon: "el-icon-s-help",roles: ['admin'],  // 当前路由对应的权限关键字,超级管理员}}
]  // 动态理由表const createRouter = () =>new Router({routes: constantRoutes // 这里只有常用路由,并没有动态路由});const route = createRouter()
export default route // 导出路由对象

2. 用户登录的时候,拿到后台返回的权限关键字,这里是admin或者ordinaryUsers。然后遍历动态路由表,动态添加路由。

// 引入路由对象和前端保存的动态路由表
import router,{ asyncRoute } from '@/router'
// 过滤符合用户权限的路由表
let arr = asyncRoute.filter(item=>{return item.meta.roles.includes('这里后台返回的权限关键字')
})
// 遍历符合权限的路由表,动态添加路由
arr.forEach(item=>{route.addRoute(item)
})
  • 第二种:前端不保存,全部由后台返回

实现思路:

  1. 前端只保存常用路由,比如登录页面、首页等。

  2. 每次用户登录成功的时候,后台返回一个路由数组,数组中每个对象包含的信息就是我们的路由对象

  3. 前端根据后台返回路由数组,通过addRoute()动态添加到路由表中

注意:

这里有一个地方需要注意,就是路由对象中的component字段,后台只会返回给我们一个字符串,但这里前端需要的是一个组件对象。所以前端需要将对象字段转换为前端组件,然后才能创建动态路由。

具体实现如下:

1. 第一步,前端只保存常用路由。

// route.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)const constantRoutes = [{path: "/login",name: "login",component: () => import("@/views/login")},{path: "/home",component: () => import("@/views/home"),redirect: "/home",name: "首页",meta: { title: "首页", icon: "el-icon-s-help" }}
];  // 常用路由表const createRouter = () =>new Router({routes: constantRoutes // 这里只有常用路由});const route = createRouter()
export default route // 导出路由对象

2. 每次登录的时候,遍历后台返回的路由数组,然后动态添加路由。

//  遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap) {const accessedRouters = asyncRouterMap.filter(route => {if (route.component) {if (route.component === "Layout") {route.component = Layout;} else {route.component = loadView(route.component); // 导入组件}}route.meta = { title: route.title, icon: route.icon || "el-icon-s-help" };route.name = route.label;if (route.children && route.children.length) {route.children = filterAsyncRouter(route.children);} else {route.children = [];}return true;});return accessedRouters;
}const loadView = view => {// 路由懒加载return resolve => require([`@/views/${view}`], resolve);
};//过滤路由
const menus = filterAsyncRouter('后台返回的路由数组');
//动态添加路由
router.addRoutes(menus);

注意:

大家注意到了,这里我用的是addRoutes,而不是addRoute。他们两个的区别就是,addRoutes需要传入路由数组,addRoute需要传入路由对象。不过在Vue3中,addRoutes已经废弃了,需要注意一下。


两种方式的对比

第一种前端自己保存一套路由表,里面的name、path、icon等字段都是前端自己控制的,这样在前端页面跳转时,更加的稳定,但是icon字段不能动态改变,也不能动态增删路由对象,每次对应角色的权限有变化的时候,前端也需要进行改动。菜单之间的顺序是固定的。

第二种全部由后台决定,里面的name、path、icon等字段都是后台返回的,路由之间的顺序也是后台决定的。所以前台菜单的icon、顺序、名称都是可以动态改变的,这里就可以做一个叫做菜单管理的模块,用来动态配置前端菜单。

但是这里需要注意,path字段和组件也是后台返回的,此时如果后台返回的path字段和前端页面跳转的path不一样的时候,会影响前端页面的跳转,组件不一样也会导致页面无法渲染出来。所以菜单管理中,对于path和组件字段是通过下拉框形式绑定的,用户不可以根据自己的意愿随意更改,以此来减少对前端页面的影响。


Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!

叶阳辉

HFun 前端攻城狮

往期精彩:

  • Vue 进阶系列丨Object 的变化侦测

  • Vue 进阶系列丨Array 的变化侦测

  • Vue 进阶系列丨虚拟DOM和VNode

  • Vue 进阶系列丨Patch 和模板编译

  • Vue 进阶系列丨事件相关的实例方法

  • Vue 进阶系列丨生命周期相关的实例方法

  • Vue 进阶系列丨生命周期

  • Vue 进阶系列丨自定义指令

  • Vue 进阶系列丨最佳实践

  • Vue 进阶系列丨Mixin 混入

Vue 进阶系列丨权限控制 addRoute()相关推荐

  1. Vue 进阶系列丨自定义指令实现按钮权限功能

    Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的.若感本文对您有所帮助请点个赞吧! 2013年7月28日,尤雨溪第一次 ...

  2. Vue 进阶系列丨vuex持久化

    Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的.若感本文对您有所帮助请点个赞吧! 2013年7月28日,尤雨溪第一次 ...

  3. Vue 进阶系列丨生命周期

    Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的.若感本文对您有所帮助请点个赞吧! 2013年7月28日,尤雨溪第一次 ...

  4. 基于Vue实现后台系统权限控制

    原文地址:http://refined-x.com/2017/08/29/基于Vue实现后台系统权限控制/,转载请注明出处. 用Vue这类双向绑定框架做后台系统再适合不过,后台系统相比普通前端项目除了 ...

  5. Vue 进阶系列(一)之响应式原理及实现

    Vue进阶系列汇总如下,欢迎阅读. Vue 进阶系列(一)之响应式原理及实现 Vue 进阶系列(二)之插件原理及实现 Vue 进阶系列(三)之Render函数原理及实现 什么是响应式Reactivit ...

  6. vue项目实现前端权限控制

    前端权限的意义 1.前端权限就是控制前端的视图层的展示和前端所发送的请求. 2. 前端权限的控制,主要由这几方面的好处 (1)降低非法早操作的可能性 (2)提高用户体验 (3)尽可能排除不必要的请求, ...

  7. Spring Boot Web应用集成Keycloak进阶之细粒度权限控制

    [](()资源管理 ======================================================================= 资源管理主要用来定义资源服务器的哪些 ...

  8. Vue 前端页面按钮权限控制

    前言 按钮权限控制的功能其实在前面的一篇的页面权限管理也包含有这个功能,但是没有凸显出来,所以现在单独写一篇文章用来记录一下 一.什么是按钮权限控制? 刚刚做完了一个后台管理系统,有用到按钮权限控制, ...

  9. k26.第十一章 K8s进阶篇-细粒度权限控制 (二)

    2. RBAC实践 创建一个名为deployment-clusterrole的clusterrole ​ a) 该clusterrole只允许创建Deployment.Daemonset.Statef ...

最新文章

  1. PHP最简单写文件记日志当前时间
  2. ts连接mysql数据库_各种数据库的连接方法
  3. ITK:获取或设置ITK类的成员变量
  4. linux 网络通讯 命令,Linux—网络通讯管理命令
  5. nginx配置 yii2 URL重写规则 SSI配置使shtml
  6. mount 挂载光盘
  7. mysql数据库索引调优
  8. redis命令执行流程分析
  9. linux虚拟环境tmux,关于在Linux系统中如何把tmux和vim打造成IDE的讲解
  10. python相机拍照显示_Python无法从Raspberry Pi相机以最高分辨率拍照
  11. 网络安全课第九节 网络安全攻防实战
  12. Linux SSH服务启动,如何打开22端口?如何开启ssh远程链接
  13. 《单片机原理及应用(魏洪磊)》第七章第8题
  14. 博士入学考题(ZZ)
  15. 错误代码warning C4013: ‘sqrt‘ undefined; assuming extern returning int怎么解决?
  16. vrf路由泄露原理和简单示例
  17. Error: errCode: -501000 | errMsg: Environment create at tencentcloud cannot access from wx-miniapp
  18. 【Educoder作业】绘制炸弹轨迹 I——绘制一个坐标点
  19. Splay(dispatching)
  20. VerA 0.15 by PE_kill

热门文章

  1. 李沐开源新作,一起来《动手学深度学习》
  2. 个人讨厌LOL的理由:该游戏及是付出和回报不平的印证
  3. 12306 抢票版插件拖垮 Github 服务器
  4. Win10 升级到 XP 系统,精简养老还能流畅扫雷
  5. Flutter仿京东
  6. 谁是卧底python代码,python基础练习之几个简单的游戏
  7. 物联网LPWA通信技术(1):NB-IOT通信特点及主要场景应用
  8. 2020年3GPP技术将达到LPWA连接的35%
  9. MOS管被ESD击穿解决方案-KIA MOS管
  10. [MRCTF2020]你传你呢 1