vue 实现后台权限管理 向右看齐 2021-09-03 07:01 666阅读 0赞 1.权限管理思路 (权限(被分配)——》角色(被分配)---------》用户) 框架采用 vue-element-admin 2,我设计是角色中直接配置权限,看界面 角色列表 ![20201129124914314.png][] 点击列表中 权限设置 打开的界面 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpbnhpbl96aHU_size_16_color_FFFFFF_t_70][] 权限设置中的树形菜单结构 id是唯一的。对应动态路由中 meta: \{ permission: "对应树形菜单中唯一的id" \}, 便于后期比对显示动态路由 { "data": [ { "label": "测试模块", "id": "test", "children": [ { "label": "测试列表", "id": "test-list", "children": [ { "label": "增加", "id": "test-add" }, { "label": "删除", "id": "test-delete" }, { "label": "修改", "id": "test-update" }, { "label": "查看", "id": "test-view" } ] } ] }, ] } 看一下动态路由 { path: 'test', component: () => import('@/views/modular/test/index'), name: 'test', alwaysShow: true, meta: { title: '测试模块', noCache: true, permission: "test", }, children: [{ path: 'test-list', component: () => import('@/views/modular/test/list'), name: 'test-list', meta: { title: '测试模块列表', noCache: true, permission: "test-list", }, }] } 4.用户列表: ![20201129130143195.png][] 点击 角色设置 选中 角色列表中的测试 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpbnhpbl96aHU_size_16_color_FFFFFF_t_70 1][] 切换用户登陆 系统用户登陆 看到的菜单 ![20201129130938146.png][] 二:代码编写 1)核心代码 vuex 中 peimission.js import { asyncRoutes, constantRoutes } from '@/router' /** * 通过meta.role判断是否与当前用户权限匹配 * @param permission * @param route */ function hasPermission(permission, route) { if(route.meta && route.meta.permission) { return permission.indexOf(route.meta.permission) != -1 } else { return false } } /** * 递归过滤异步路由表,返回符合用户角色权限的路由表 * @param routes asyncRoutes * @param permission */ export function filterAsyncRoutes(routes, permission) { const res = [] routes.forEach(route => { const tmp = { ...route } if (tmp.children) { tmp.children = filterAsyncRoutes(tmp.children, permission) if (tmp.children && tmp.children.length > 0) { res.push(tmp) } } else { if (hasPermission(permission, tmp)) { res.push(tmp) } } }) return res } const permission = { state: { routes: [], addRoutes: [] }, mutations: { SET_ROUTES: (state, routes) => { state.addRoutes = routes state.routes = constantRoutes.concat(routes) } }, actions: { GenerateRoutes({ commit }, data) { return new Promise(resolve => { const { permission } = data let accessedRoutes; if(permission.indexOf("*") != -1) { accessedRoutes = asyncRoutes; } else { accessedRoutes = filterAsyncRoutes(asyncRoutes, permission) } commit('SET_ROUTES', accessedRoutes) resolve(accessedRoutes) }) } } } export default permission 按钮权限检查代码 untis->permission.js import store from '@/store' /** * @param {Array} value * @returns {Boolean} * @example see @/views/permission/directive.vue */ export default function checkPermission (value) { const permissions = store.getters && store.getters.permission if (permissions && permissions instanceof Array && permissions.includes("*")) return true if (value && value instanceof Array && value.length > 0) { const hasPermission = permissions.some(permission => { return value.includes(permission) }) if (!hasPermission) return false return true } else if (value && typeof value == 'string') { return permissions.includes(value) } else { return false } } mian.js中 import Vue from 'vue' import 'normalize.css/normalize.css' // A modern alternative to CSS resets import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' //import locale from 'element-ui/lib/locale/lang/zh-CN' // lang i18n import '@/styles/index.scss' // global css import App from './App' import store from './store' import router from './router' import '@/icons' // icon import '@/permission' // permission control import Avue from '@smallwei/avue'; import '@smallwei/avue/lib/index.css'; import '@/assets/css/index.scss' /** * If you don't want to use mock-server * you want to use MockJs for mock api * you can execute: mockXHR() * * Currently MockJs will be used in the production environment, * please remove it before going online ! ! ! */ // if (process.env.NODE_ENV === 'production') { // const { mockXHR } = require('../mock') // mockXHR() // } Vue.prototype.checkPermission = require("@/utils/permission").default // set ElementUI lang to EN Vue.use(Avue);//使用AVUE Vue.use(ElementUI) // 如果想要中文版 element-ui,按如下方式声明 // Vue.use(ElementUI) Vue.config.productionTip = false new Vue({ el: '#app', router, store, render: h => h(App) }) mian.js 中 引入的这个文件 import '@/permission' 和main.js 平级 import router from './router' import store from './store' import { Message } from 'element-ui' import NProgress from 'nprogress' // progress bar import 'nprogress/nprogress.css' // progress bar style import { getToken } from '@/utils/auth' // get token from cookie NProgress.configure({ showSpinner: false }) // NProgress Configuration function hasPermission(permissions, permission) { if (!permission || permission == 'home' || permissions.indexOf("*") != -1) { return true } return permissions.indexOf(permission) != -1 } const whiteList = ['/login','/auth-redirect'] // no redirect whitelist router.beforeEach((to, from, next) => { NProgress.start() if (to.meta.title) { document.title = "cq-" + to.meta.title; } else { document.title = "cqadmin"; } const hasToken = getToken() if (hasToken) { if (to.path === '/login') { next({ path: '/' }) NProgress.done() } else { if (store.getters.permission.length === 0) { store.dispatch('user/getInfo').then(res => { const permission = res.results.permission if (res.results.is_admin) { res.results.permission.push('*') } if (permission.length) { store.dispatch('GenerateRoutes', res.results).then(accessRoutes => { // 根据后台查询出的菜单权限生成可访问的路由表 router.addRoutes(accessRoutes) // 动态添加可访问路由表 router.options.routes=store.getters.routers; //很重要的一句 next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 }) } else { next({ path: '/401', replace: true, query: { noGoBack: true } }) } }).catch(err => { store.dispatch('FedLogOut').then(() => { Message.error(err) next({ path: '/' }) }) }) }else { // debugger //next() if (hasPermission(store.getters.permission, to.meta.permission)) { // 有权限 next() } else { // 无权限 next({ path: '/401', replace: true, query: { noGoBack: true } }) } } } } else { /* has no token*/ if (whiteList.indexOf(to.path) !== -1) { // in the free login whitelist, go directly next() } else { // other pages that do not have permission to access are redirected to the login page. next(`/login?redirect=${to.path}`) NProgress.done() } } }) router.afterEach(() => { // finish progress bar NProgress.done() }) 参考:[https://blog.csdn.net/qq\_33705529/article/details/103582472?utm\_medium=distribute.pc\_relevant\_bbs\_down.none-task-blog-baidujs-1.nonecase&depth\_1-utm\_source=distribute.pc\_relevant\_bbs\_down.none-task-blog-baidujs-1.nonecase][https_blog.csdn.net_qq_33705529_article_details_103582472_utm_medium_distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase_depth_1-utm_source_distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase] [20201129124914314.png]: /images/20210730/d1db193a74824ea4b0ffcea66943f72f.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpbnhpbl96aHU_size_16_color_FFFFFF_t_70]: /images/20210730/d8bfcdf566174631ba0696e207c7dd22.png [20201129130143195.png]: /images/20210730/df2e3db133974ff0af45f30a14aa24fe.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpbnhpbl96aHU_size_16_color_FFFFFF_t_70 1]: /images/20210730/1f5d131c3f5b4bc883586b970a43cf51.png [20201129130938146.png]: /images/20210730/fc4b90dc3775487ea23c64b4e9b7b02a.png [https_blog.csdn.net_qq_33705529_article_details_103582472_utm_medium_distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase_depth_1-utm_source_distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase]: https://blog.csdn.net/qq_33705529/article/details/103582472?utm_medium=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase
还没有评论,来说两句吧...