无法在这个位置找到: head2.htm
当前位置: 建站首页 > 新闻动态 > 行业新闻 >

解题微信小程序模版_详解使用 Vue.js 完成前后端

时间:2021-01-11 14:26来源:解题微信小程序模版 作者:jianzhan 点击:
详细说明运用 Vue.js 完成前后左右端分离出来的RBAC人物角色管理权限管理方法 新项目情况:物业管理管理方法后台管理,不一样人物角色有着不一样管理权限选用技术性:Vue.js
详解利用 Vue.js 实现前后端分离的RBAC角色权限管理       本篇文章主要介绍了利用 Vue.js 实现前后端分离的RBAC角色权限管理,非常具有实用价值,需要的朋友可以参考下

项目背景:物业管理后台,不同角色拥有不同权限

采用技术:Vue.js + Vuex + Element UI

实现 RBAC 权限管理需要后端接口支持,这里仅提供前端解决方案。

因代码篇幅较大,对代码进行了删减,文中 “...” 即为省略的一部分代码。

大致思路:
首先登录成功后,从后台拉取用户当前可显示的菜单和可用权限列表,分别将其存入 store 的 nav(菜单导航) 和 auth(用户可用权限) 中,在用户切换路由时,判断是否存在 auth ,如果不存在,则重新获取,判断当前访问地址 to.meta.alias 是否在用户可用权限列表中,如果不存在,则提示无权限,否则进入路由。

1. 路由与侧边菜单分离

侧边菜单相关代码 Main.vue

 template 
 !-- ... -- 
 aside :class="colla凡科抠图ed 'menu-colla凡科抠图ed':'menu-expanded'" 
 !--导航菜单-- 
 el-menu :default-active="$route.path"
 @open="handleopen"
 @close="handleclose"
 @select="handleselect"
 :colla凡科抠图e="colla凡科抠图ed"
 unique-opened router 
 template v-for="(item,index) in nav" 
 !-- 二级菜单 -- 
 el-submenu :index="index+''"
 v-if="item.children item.children.length 0" 
 !-- 二级菜单顶级 -- 
 template slot="title" 
 i :class="['icon',item.iconCls]" /i 
 span slot="title" {{item.name}} /span 
 /template 
 !-- 二级菜单下级 -- 
 el-menu-item-group 
 !-- span slot="title" {{item.name}} /span -- 
 !-- child.url-- 
 template v-for="child in item.children" 
 !--无三级菜单-- 
 el-menu-item
 :index="child.url"
 :key="child.url"
 v-if="!child.children" 
 {{child.name}}
 /el-menu-item 
 !--有三级菜单-- 
 el-submenu
 :index="child.url"
 :key="child.url"
 v-if="child.children" 
 span slot="title" {{child.name}} /span 
 el-menu-item v-for="subChild in child.children"
 :index="subChild.url"
 :key="subChild.url" 
 {{subChild.name}}
 /el-menu-item 
 /el-submenu 
 /template 
 /el-menu-item-group 
 /el-submenu 
 !-- 一级菜单 -- 
 el-menu-item v-if="!item.children"
 :index="item.url" 
 i :class="['icon',item.iconCls]" /i 
 span slot="title" {{item.name}} /span 
 /el-menu-item 
 /template 
 /el-menu 
 /aside 
 !-- ... -- 
 /template 
 script 
 export default {
 // ...
 computed: {
 // 从 Vuex 中获取导航菜单
 nav() {
 return this.$store.state.nav;
 // ...
 /script 

2. 路由切换前进行鉴权

路由定义的部分代码,对每个路由添加了 meta 属性,用于鉴权。

定义路由

// ...
// 系统管理
path: '/system',
component: Main,
name: '系统管理',
redirect: '/anization',
children: [{
 path: '/anization',
 component: () = import ('@/views/System/Organization.vue'),
 name: '组织结构',
 // requiresAuth 用于确认此地址是否需要验证
 // alias 用于获取后端返回rbac权限对应的前端路由地址和导航菜单图标
 meta: {requiresAuth: true, alias: 'Pmsadmin/Oragnize/list'}
 path: '/system/user',
 component: () = import ('@/views/System/User.vue'),
 name: '人员管理',
 redirect: '/system/user/index',
 children: [
 path: '/system/user/index',
 component: () = import ('@/views/System/UserList.vue'),
 name: '职员列表',
 meta: {requiresAuth: true, alias: 'Pmsadmin/Admin/list'}
 path: '/system/auth',
 component: () = import ('@/views/System/Auth.vue'),
 name: '角色管理',
 meta: {requiresAuth: true, alias: 'Pmsadmin/Role/list'}
// ...

路由钩子 beforeEach

router.beforeEach((to, from, next) = {
 document.title = `${configs.title} - ${to.name}`;
 const {hasAuth, auth} = store.state.user;
 // 未拿到权限,则获取
 if (!hasAuth) {
 store.dispatch('getUserAuth');
 console.log('重新获取用户权限');
 // next();
 // 如果未登录,跳转
 if (window.localStorage.getItem('IS_LOGIN') === null to.path !== '/login') {
 console.log('未登录状态');
 next({
 path: '/login',
 query: {redirect: to.fullPath}
 // 将跳转的路由path作为参数,登录成功后跳转到该路由
 } else {
 // 需要鉴权的路由地址
 console.log(to, auth.indexOf(to.meta.alias), auth);
 if (to.meta.requiresAuth) {
 if (auth.indexOf(to.meta.alias) -1) {
 console.log('有权限进入');
 next();
 } else {
 if(auth.length 0) {
 Message.error({
 message: '当前用户权限不足,无法访问',
 showClose: true,
 } else {
 next();
 } else {
 next();

在 Vuex 的 state 中,定义好 nav 对象

// 登录用户信息
const user = {
 name: '', // 用户名
 avatar: '', // 用户头像
 auth: [], // 用户权限
 hasAuth: false // 是否已经加载用户权限
// 导航菜单
const nav = [];

通过 action 异步获取数据

// 获取用户权限
const getUserAuth = async ({commit}) = {
 const res = await http.post('YOUR_URL', {});
 if (res === null) return;
 console.log('getUserAuth', res.param);
 commit('SET_USER_AUTH', res.param.auth);
 commit('SET_SIDE_NAV', res.param.nav);

Vuex 中的 mutation 的相关代码

// 设置用户权限
const SET_USER_AUTH = (state, auth) = {
 state.user.auth = auth.concat('欢迎使用');
 state.user.hasAuth = true;
// 设置导航菜单
const SET_SIDE_NAV = (state, nav) = {
 // 导航菜单
 let _nav = [{
 name: '欢迎使用',
 url: "/main",
 iconCls: 'fa fa-bookmark'
 // 权限菜单对应的路由地址
 const route = {
 "系统管理": {iconCls: 'fa fa-archive', url: ''},
 "Pmsadmin/Oragnize/list": {iconCls: '', url: '/anization'},
 "Pmsadmin/Admin/list": {iconCls: '', url: '/system/user/index'},
 "Pmsadmin/Role/list": {iconCls: '', url: '/system/auth'},
 "Pmsadmin/Log/record": {iconCls: '', url: '/system/logs'},
 "项目管理": {iconCls: 'fa fa-unlock-alt', url: ''},
 "Pmsadmin/Project/list": {iconCls: '', url: '/project/list/index'},
 "Pmsadmin/House/list": {iconCls: '', url: '/project/house'},
 "Pmsadmin/Pack/list": {iconCls: '', url: '/project/pack'},
 "广告位": {iconCls: 'fa fa-edit', url: ''},
 "Pmsadmin/Place/list": {iconCls: '', url: '/adsplace/list'},
 "投诉建议": {iconCls: 'fa fa-tasks', url: ''},
 "Pmsadmin/Scategory/list": {iconCls: '', url: '/complain/type'},
 "Pmsadmin/Complain/list": {iconCls: '', url: '/complain/list'},
 "Pmsadmin/Suggest/list": {iconCls: '', url: '/complain/suggestion'},
 "报事报修": {iconCls: 'fa fa-user', url: ''},
 "Pmsadmin/Rcategory/list": {iconCls: '', url: '/rcategory/type'},
 "": {iconCls: '', url: '/rcategory/public'},
 "Pmsadmin/Repair/list": {iconCls: '', url: '/rcategory/personal'},
 "便民服务": {iconCls: 'fa fa-external-link', url: ''},
 "Pmsadmin/Bcategory/list": {iconCls: '', url: '/bcategory/type'},
 "Pmsadmin/Service/list": {iconCls: '', url: '/bcategory/list'},
 "首座推荐": {iconCls: 'fa fa-file-text', url: ''},
 "Pmsadmin/stcategory/list": {iconCls: '', url: '/stcategory/type'},
 "Pmsadmin/Store/list": {iconCls: '', url: '/stcategory/list'},
 "招商租赁": {iconCls: 'fa fa-leaf', url: ''},
 "Pmsadmin/Bussiness/list": {iconCls: '', url: '/bussiness/list'},
 "Pmsadmin/Company/list": {iconCls: '', url: '/pany'},
 "Pmsadmin/Question/list": {iconCls: '', url: '/bussiness/question'},
 "停车找车": {iconCls: 'fa fa-ra', url: ''},
 "Pmsadmin/Cplace/list": {iconCls: '', url: '/cplace/cmanage'},
 "Pmsadmin/Clist/list": {iconCls: '', url: '/cplace/clist'},
 "Pmsadmin/Cquestion/list": {iconCls: '', url: '/cplace/cquestion'},
 for (let key in nav) {
 let item = nav[key];
 let _temp = {};
 let subItems = []; // 二级菜单临时数组
 if (item.children item.children.length 0) {
 // 二级菜单
 item.children.forEach(subItem = {
 subItems.push(Object.assign({}, {
 name: subItem.name || '',
 url: route[subItem.url].url || '',
 iconCls: route[subItem.url].iconCls || '',
 // 一级菜单
 _temp = Object.assign({}, {
 name: item.name || '',
 url: item.url || '',
 iconCls: route[item.name].iconCls || '',
 children: subItems.slice(0)
 _nav.push(_temp);
 state.nav = _nav;

3. 后端接口返回内容

 "status": 200,
 "info": "数据查询成功!",
 "param": {
 "nav": {
 "1": {
 "name": "系统管理",
 "url": "",
 "children": [
 "name": "组织结构",
 "url": "Pmsadmin/Oragnize/list"
 "name": "人员管理",
 "url": "Pmsadmin/Admin/list"
 "name": "角色管理",
 "url": "Pmsadmin/Role/list"
 "name": "日志管理",
 "url": "Pmsadmin/Log/record"
 "61": {
 "name": "广告位",
 "url": "",
 "children": [
 "name": "广告位列表",
 "url": "Pmsadmin/Place/list"
 "auth": [
 "系统管理",
 "Pmsadmin/Oragnize/list",
 "Pmsadmin/Admin/list",
 "Pmsadmin/Role/list",
 "Pmsadmin/Log/record",
 "广告位",
 "Pmsadmin/Place/list"

存在的问题

新增 修改 删除 按钮还无法实现根据用户权限控制其显示 代码上还存在着不足,期待大神能够有更优的解决方案。

(责任编辑:admin)
织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
无法在这个位置找到: ajaxfeedback.htm
栏目列表
推荐内容


扫描二维码分享到微信