Vue+element搭建后台管理系统-六、实现权限管理
在一些后台管理系统中,每个身份登录的权限不一样,以至于配置的菜单不一样。就我做过的小区物业管理系统而言,举个例子:业主登录网站只能看到社区服务中的投诉、维修以及查看公告。而管理员可以看到一些对本小区的基本操作,例如查看楼栋,查看业主,账单催缴等等…而超级管理员,可以看到所有界面,以及处理一些审核等等一系列。那么这个时候,我们没必要每个身份做一个系统,而是通过权限管理,对每种身份做配置;
————————————————
上述引用自:CSDN博主「一坨仙女」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_51462774/article/details/117194323
权限管理的实现,其实是需要后台配合的,也可能会根据不同的需求有不同的实现方法。这章的内容主要说要一下我们公司之前后台管理系统的实现思路。
先给同学们描述一下具体的实现步骤:
1、用户登录
2、返回权限数据
3、根据权限数据写拦截器
一、约定权限数据
也就是首先要向后台所有的权限数据放到配置文件中,我这里做的是一个json数组,将每个路由名称映射到每个对应的权限上面,入下图所示:
由于具体代码就不贴了,可以根据截图在config文件夹下创建config.permission.js文件,然后把每个权限做成键值对,键名可以通过权限对应的内容来命名,这个键名后面在路由配置文件中是用到的。
二、用户登录缓存权限数据
当用户登录成功之后,拿到了对应的权限数据,这些权限数据有很多地方要用到,所以我们需要做成缓存,一般的话是通过Vuex来缓存,不过这个有个弊端,就是页面F5刷新之后会丢失。也可以缓存到浏览器的storeage,建议存本地缓存的应使用加密方式进行存储。
先实现个登录页面,在view/login/ 文件夹下新建 index.vue 文件,代码如下:
<template> <div> <h5>我是登录</h5> <input type="text" v-model="username" placeholder="请输入用户名" /> <input type="password" v-model="password" placeholder="请输入密码" /> <button @click="login">登录</button> </div> </template> <script> export default { data() { return { username: '', password: '', } }, methods: { login() { this.$ajax('login/authApi/loginApi', { usernmae: this.username, passwrod: this.password }) .then((res) => { console.log('success', JSON.stringify(res)) }) .catch((rej) => { console.log('fail', rej) }) }, }, } </script>
在App.vue中添加router-view组件:
<template> <div id="app"> <router-view></router-view> </div> </template> <script> export default { name: 'App', components: { }, methods: { }, } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
记得之前的代码是把路由跳转给关闭掉了,现在把它开放出来。更改router/index.js 文件
/** * 全局前置守卫 * @func beforeEach * @param {object} to 即将要进入的目标 路由对象 * @param {object} form 当前导航正要离开的路由 * @func next 进行管道中的下一个钩子 */ router.beforeEach(async (to, from, next) => { next() })
在router/routers.js 导入页面模块:
/** * 逐个导出模块 */ export const constantRoutes = [ { path: '/', redirect: '/home' }, { path: '/login', name: 'login', meta: { title: '登录', }, component: () => import('../views/login/index.vue') } ] export default [ ...constantRoutes, ]
在使用import导入页面模块,由于之前加的代码规范,是会报错的,我们在.eslintrc.js文件加入以下代码就可以了。
//import模块导入 parserOptions: { parser: 'babel-eslint', ecmaVersion: 10, sourceType: 'module', }, //import模块导入
最后在浏览器地址栏中后面加上/login,就能看到正常跳转了。
三、路由拦截器
权限控制就是判断你有哪些权限就可以访问哪些内容,这里我们来处理一下路由跳转的拦截。
先写一个简单的拦截器,就在utils文件夹下创建intercept文件夹和has-permission.js文件,实际就是一个工具类,根据传入的权限标识用来判断是否有权限。
import store from '@/store' import permissionsJson from '@/config/config.permission.js' /** * 判断用户是否拥有操作权限 * 根据传入的权限标识,查看是否存在用户权限标识集合 * @param perms */ export function hasPermission(perms) { let hasPermission = false let permissions = store.state.user.perms if (permissions.length == 0) { return false } for (let i = 0, len = permissions.length; i < len; i++) { if (permissions[i] === permissionsJson[perms]) { hasPermission = true break } } return hasPermission }
导入的store模块:
主要是取登录之后的权限数据,在store/modules/user.js加一下perms属性,
export default { namespaced: true, state: { userInfo: { id: null, account: '', realName: '', companies: '', sites: null, }, perms: [], //权限集合 }, mutations: { setUserInfo(state, param) { state.userInfo = param }, logout(state, param) { state.userInfo = param }, setPerms(state, perms){ // 用户权限标识集合 state.perms = perms } }, }
然后在登录页面中,在点击登录请求后,通this.$store.commit 缓存权限状态。这里插一句,this.$store.commit 是传值给vuex中的mutation改变state,这个是同步的方法,异步的是this.$store.dispatch。
登录页的代码如下:
<template> <div> <h5>我是登录</h5> <input type="text" v-model="username" placeholder="请输入用户名" /> <input type="password" v-model="password" placeholder="请输入密码" /> <button @click="login">登录</button> </div> </template> <script> export default { data() { return { username: '', password: '', } }, methods: { login() { this.$ajax('login/authApi/loginApi', { usernmae: this.username, passwrod: this.password }) .then(() => { // console.log('success', JSON.stringify(res)) //模拟登录成功-状态缓存权限数据 this.$store.commit('user/setPerms', ['ruleList', 'scenicList']) this.$router.push('home') }) .catch((rej) => { console.log('fail', rej) }) }, }, } </script>
上面api的接口的实现,是通过mockJS实现的,在前端开发过程中,对于mock数据的应用也是很重要的,太久没写博客了,忘记前面有没有细讲mockJS导入和使用的问题。如果没有的话,后面我会用一章节单独说这个内容。
在view文件夹中创建home页面
然后在路由中引入:router/routers.js
在权限管理的实现中,一般会分为两种实现,功能模块的控制显示和路由页面的控制跳转。
功能模块的控制显示。
在home页面中,查看获取到的权限列表;
上面是没有加权限控制显示的按钮,通过循环显示加上控制显示。
view/home/home.vue代码如下:
<template> <div> <h5>我是主页</h5> <template v-for="item in menuList"> <el-button v-if="showBtn(item.persName)" :key="item.persName" :type="item.type">{{ item.name }}</el-button> </template> </div> </template> <script> // import { mapState } from 'vuex' import { hasPermission } from '../../utils/intercept/has-permission' export default { data() { return { menuList: [ { type: 'primary', name: '预约管理', persName: 'preorder', }, { type: 'success', name: '预约管理-预约记录', persName: 'orderRecord', }, { type: 'info', name: '预约管理-预约数据统计', persName: 'orderStatistics', }, { type: 'warning', name: '预约管理-规则设置', persName: 'ruleSet', }, { type: 'danger', name: '预约管理-规则查询', persName: 'ruleList', }, ], } }, computed: { // ...mapState({ // permissionList: (state) => state.user.perms, // }), permissionList() { return this.$store.state.user.perms }, }, created() { // console.log('权限数据', this.$store.state.user.perms) }, methods: { showBtn(persName) { console.log('打印权限', persName, hasPermission(persName)) return hasPermission(persName) }, }, } </script>
路由页面的控制跳转。
在路由跳转前置中做好控制,根据权限拦截,有权限通过,没权限就提示无权限。
在router/index.js中引入权限判断函数
import { hasPermission } from '../utils/intercept/has-permission'
修改路由跳转的前置函数:
在需要权限访问的页面中,注册路由的时候,在meta属性中加入persName属性,并添加具体的权限名;如订单页面:
当点击home页面的进行测试,可以看到,对没有权限的页面跳转进行了拦截;
即使知道路由名称,在地址栏中输入访问,也是不起效果的。
-----------------------======================================================================-----------------------
那么后台管理系统实现权限管理这个章节也算讲完了,内容有点多,希望大家好好消化一下,多动动手。
一直忘记把代码仓库发出来了,抱歉~
附上代码仓库:baskstate-sys: 前端修仙之路-后台管理系统框架-源码 配套学习:博客园-https://www.cnblogs.com/liao123/p/16168755.html 公众号:padding2020 (gitee.com)