vue权限路由实现的方法示例总结_vue.js_脚本之家【

来源:http://www.chinese-glasses.com 作者:Web前端 人气:199 发布时间:2020-05-06
摘要:因此,下文我会和大家分享两种方式实现动态菜单,这两种方式仅仅只是探讨如何更好的给用户展示菜单,而不是探讨权限管理,因为权限管理是在后端完成的,也必须在后端完成。

因此,下文我会和大家分享两种方式实现动态菜单,这两种方式仅仅只是探讨如何更好的给用户展示菜单,而不是探讨权限管理,因为权限管理是在后端完成的,也必须在后端完成。

addRoutes允许在应用初始化之后,动态的挂载路由。有了这个新姿势,就不用像前一种方式那样要在应用初始化之要对路由进行筛选。

不过在公司中,动态菜单到底在前端做还是后端做,可能会有一个前后端团队沟(si)通(bi)的过程,赢了的一方就可以少写几行代码了。

这是什么鬼,明显不行。() => import这代码如果没出现在前端,webpack不会对Login.vue进行编译打包

2.2 前端动态渲染

 import { getAccessMenuList } from "../mock/menus";import components from "../router/routerComponents.js";export default { async mounted() { if (!this.$store.state.isLogin) { this.$router.push; return; } if (!this.$store.state.initedApp) { const loading = this.$loading({ lock: true, text: "初始化中", spinner: "el-icon-loading", background: "rgba; let menus = await getAccessMenuList(); //模拟从后端获取 var routers = [...menus]; for (let router of routers) { let component = components[router.component]; router.component = component; } this.$router.addRoutes; this.$store.dispatch("setAccessMenuList", menus).then => { loading.close(); this.$router.replace; return; } else { this.$router.replace; } }};
  1. 结语

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

[ { "id":2, "path":"/home", "component":Home, "name":"员工资料", "iconCls":"fa fa-user-circle-o", "children":[ { "id":null, "path":"/emp/basic", "component":EmpBasic, "name":"基本资料", "iconCls":null, "children":[ ], "meta":{ "keepAlive":false, "requireAuth":true, "roles":['admin','user'] } } ], "meta":{ "keepAlive":false, "requireAuth":true } }]

name字段都不为空,需要根据此字段与后端返回菜单做关联。

做权限管理,一个核心思想就是后端做权限控制,前端做的所有工作都只是为了提高用户体验,我们不能依靠前端展示或者隐藏一个按钮来实现权限控制,这样肯定是不安全的。

如果已经初始化,跳转/路由(如果后端返回的路由里没有定义次路由,则会跳转404)。

2.1 后端动态返回

上面代码是vue-quasar-admin的实现。因为没有使用addRoutes,每次路由跳转的时候都要判断权限,这里的判断也很简单,因为菜单的name与路由的name是一一对应的,而后端返回的菜单就已经是经过权限过滤的,所以如果根据路由name找不到对应的菜单,就表示用户有没权限访问。

这样的 JSON 在前端中再进行二次处理之后,就可以使用了,前端的二次处理主要是把 component 属性的字符串值转为对象。这一块具体操作大家可以参考微人事项目(具体在:),我就不再赘述了。

如果路由很多,可以在应用初始化的时候,只挂载不需要权限控制的路由。取得后端返回的菜单后,根据菜单与路由的对应关系,筛选出可访问的路由,通过addRoutes动态挂载。

这种方式就是我直接在前端把所有页面都在路由表里边定义好,然后在 meta 属性中定义每一个页面需要哪些角色才能访问,例如下面这样:

缺点

其中hr表就是用户表,用户登录成功之后,可以查询到用户的角色,再根据用户角色去查询出来用户可以操作的菜单(资源),然后把这些可以操作的资源,组织成一个 JSON 数据,返回给前端,前端再根据这个 JSON 渲染出相应的菜单。以微人事为例,我们返回的 JSON 数据格式如下:

const constRouterMap = [ { name: "login", path: "/login", component: () => import }, { path: "/404", component: () => import("@/pages/Page404.vue") }, { path: "/init", component: () => import }, { path: "*", redirect: "/404" }];

export default constRouterMap;import Vue from "vue";import Router from "vue-router";import ConstantRouterMap from "./routers";Vue.use;export default new Router({ // mode: 'history', // require service support scrollBehavior: , routes: ConstantRouterMap});

submitForm { let _this=this; this.$refs[formName].validate { _this.$store.dispatch("loginByUserName",{ name:_this.ruleForm2.name, pass:_this.ruleForm2.pass }).then=>{ _this.$router.push } else { return false; } }); }

这种方式的一个好处是前端的判断逻辑少一些,后端也不算复杂,就是一个 SQL 操作,前端拿到后端的返回的菜单数据,稍微处理一下就可以直接使用了。另外这种方式还有一个优势就是可以动态配置资源-角色以及用户-角色之间的关系,进而调整用户可以操作的资源(菜单)。

init组件里判断应用是否已经初始化(避免初始化后,直接从地址栏输入地址再次进入当前组件)。

这是非常重要的一点,做前后端分离开发中的权限管理,我们首先要建立上面这样的思考框架,然后在这样的框架下,去考虑其他问题。

后端直接根据用户权限返回可访问的菜单。

动态菜单就是用户登录之后看到的菜单,不用角色的用户登录成功之后,会看到不用的菜单项,这个动态菜单要怎么实现呢?整体来说,有两种不同的方案,松哥曾经做过的项目中,两种方案也都有用过,这里分别来和大家分享一下。

[ { name: "home", path: "/", component: "home" }, { name: "home", path: "/userinfo", component: "userInfo" }]

这样的话,后端只需要在登录成功后返回当前用户的角色就可以了,剩下的事情则交给前端来做。不过这种方式有一个弊端就是菜单和角色的关系在前端代码中写死了,以后如果想要动态调整会有一些不方便,可能需要改代码。特别是大项目,权限比较复杂的时候,调整就更麻烦了,所以这种方式我一般建议在一些简单的项目中使用。

没有初始化,则调用远程接口获取菜单和路由等,然后处理后端返回的路由,将component赋值为真正的组件,接着调用addRoutes挂载新路由,最后跳转/路由即可。菜单的处理也是在此处,看实际需求。

后端动态返回,这是我在微人事中采用的方案。微人事中,权限管理相关的表一共有五张表,如下:

目前iview-admin还是用的这种方式

这样定义表示当前登录用户需要具备 admin 或者 user 角色,才可以访问 EmpBasic 组件,当然这里不是说我这样定义了就行,这个定义只是一个标记,在项目首页中,我会遍历这个数组做菜单动态渲染,然后根据当前登录用户的角色,再结合当前组件需要的角色,来决定是否把当前组件所对应的菜单项渲染出来。

const routerMap = [ { path: '/permission', component: Layout, redirect: '/permission/index', alwaysShow: true, // will always show the root menu meta: { title: 'permission', icon: 'lock', roles: ['admin', 'editor'] // you can set roles in root nav }, children: [{ path: 'page', component: () => import('@/views/permission/page'), name: 'pagePermission', meta: { title: 'pagePermission', roles: ['admin'] // or you can only set roles in sub nav } }, { path: 'directive', component: () => import('@/views/permission/directive'), name: 'directivePermission', meta: { title: 'directivePermission' // if do not set roles, means: this page does not require permission } }] }]
  1. 具体实现

针对前一种实现方式的缺点,可以将登录页与主应用放到不同的页面。

虽然我在微人事中使用了第一种方式,不过如果小伙伴是一个新项目,并且权限问题不是很复杂的话,我还是建议尝试一下第二种方式,感觉要方便一些。

登录成功后,进行页面跳转,并将用户权限传递到主应用所在页面,主应用初始化之前,根据用户权限筛选路由,筛选后的路由作为vue的实例化参数,而不是像前一种方式所有的路由都传递进去,也不需要在全局路由守卫里做权限判断了。

[ { "id":2, "path":"/home", "component":"Home", "name":"员工资料", "iconCls":"fa fa-user-circle-o", "children":[ { "id":null, "path":"/emp/basic", "component":"EmpBasic", "name":"基本资料", "iconCls":null, "children":[ ], "meta":{ "keepAlive":false, "requireAuth":true } } ], "meta":{ "keepAlive":false, "requireAuth":true } }]
 404export default { name:'page404', mounted(){ if(!this.$store.state.isLogin){ this.$router.replace; return; } if(!this.$store.state.initedApp){ this.$router.replace; return } }}

另一种方式就是前端动态渲染,这种方式后端的工作要轻松一些,前端处理起来麻烦一些,松哥去年年末帮一个律所做的一个管理系统,因为权限上比较容易,我就采用了这种方案。

缺点

就像用户注册时需要输入邮箱地址,前端校验之后,后端还是要校验,两个校验目的不同,前端校验是为了提高响应速度,优化用户体验,后端校验则是为了确保数据完整性。权限管理也是如此,前端按钮的展示/隐藏都只是为了提高用户体验,真正的权限管理需要后端来实现。

这种方式,菜单可以直接用路由生成(用户没有权限的菜单也会显示,点击跳转的时候才做权限判断),也可以在用户登录后根据用户权限把路由过滤一遍生成菜单。

一旦建立起这样的思考框架,你会发现动态菜单的实现办法太多了。

404组件里判断已经登录,接着判断应用是否已经初始化(用户权限信息,可访问菜单,路由等是否已经从后端取得)。没有初始化则跳转到/init路由

时间: 2019-09-11阅读: 109标签: 菜单1. 一个原则

全局路由守卫里,每次路由跳转都要做判断 菜单信息写死在前端,要改个显示文字或权限信息,需要重新编译 菜单跟路由耦合在一起,定义路由的时候还有添加菜单显示标题,图标之类的信息,而且路由不一定作为菜单显示,还要多加字段进行标识

总结

实现

所以addRoutes还是要在全局路由守卫里进行调用

function hasPermission { if (whiteList.indexOf { return true; } let menu = Util.getMenuByName(router.name, accessMenu); if  { return true; } return false;}Router.beforeEach(async  => { if  { let userInfo = store.state.user.userInfo; if  { try { await store.dispatch await store.dispatch if  { next({ name: 'home_index' }) } else { //Util.toDefaultPage([...routers], to.name, router, next); next({ ...to, replace: true })//菜单权限更新完成,重新进一次当前路由 } } catch  { if (whiteList.indexOf { // 在免登录白名单,直接进入 next() } else { next } } } else { if  { next({ name: 'home_index' }) } else { if (hasPermission(to, store.getters.accessMenu)) { Util.toDefaultPage(store.getters.accessMenu,to, routes, next); } else { next({ path: '/403',replace:true }) } } } } else { if (whiteList.indexOf { // 在免登录白名单,直接进入 next() } else { next } } let menu = Util.getMenuByName(to.name, store.getters.accessMenu); Util.title;Router.afterEach => { window.scrollTo;

实现

在404页面做了判断,感觉比较怪异 多引入了一个init页面组件

登录页与主应用分离

{ name: "login", path: "/login", component: () => import}

{ "name": "login", "path": "/login", "component": "() => import"}

在将后端返回路由通过addRoutes动态挂载之间,需要将数据处理一下,将component字段换为真正的组件。

应用初始化的时候只挂载不需要权限控制的路由

菜单的显示标题,图片等需要随时更改,要对菜单做管理功能。

前端定义好路由,并且在路由上标记相应的权限信息

本文由10bet发布于Web前端,转载请注明出处:vue权限路由实现的方法示例总结_vue.js_脚本之家【

关键词:

最火资讯