亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

詳解利用 Vue.js 實現前后端分離的RBAC角色權限管理

2019-11-19 15:26:19
字體:
來源:轉載
供稿:網友

項目背景:物業管理后臺,不同角色擁有不同權限

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

實現 RBAC 權限管理需要后端接口支持,這里僅提供前端解決方案。

因代碼篇幅較大,對代碼進行了刪減,文中 “...” 即為省略的一部分代碼。

大致思路:
首先登錄成功后,從后臺拉取用戶當前可顯示的菜單和可用權限列表,分別將其存入 store 的 nav(菜單導航) 和 auth(用戶可用權限) 中,在用戶切換路由時,判斷是否存在 auth ,如果不存在,則重新獲取,判斷當前訪問地址 to.meta.alias 是否在用戶可用權限列表中,如果不存在,則提示無權限,否則進入路由。

1. 路由與側邊菜單分離

側邊菜單相關代碼 Main.vue

<template><!-- ... -->  <aside :class="collapsed?'menu-collapsed':'menu-expanded'">    <!--導航菜單-->    <el-menu :default-active="$route.path"         class="el-menu-vertical-aliyun"          @open="handleopen"         @close="handleclose"         @select="handleselect"         :collapse="collapsed"         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 屬性,用于鑒權。

這里 component 采用了異步引入的方式。

定義路由

// ...// 系統管理{path: '/system',component: Main,name: '系統管理',redirect: '/system/organization',children: [{ path: '/system/organization', 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: '/system/organization'},  "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'},  "Pmsadmin/Rcategory/info": {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: '/bussiness/company'},  "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"    ]  }}

存在的問題

  • 新增 修改 刪除 按鈕還無法實現根據用戶權限控制其顯示
  • 代碼上還存在著不足,期待大神能夠有更優的解決方案。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产视频观看一区| 91系列在线播放| 91精品国产成人www| 亚洲国产欧美一区二区三区同亚洲| 日韩成人高清在线| 日韩成人在线视频| 欧美日韩亚洲视频一区| 久久精品国产成人精品| 亚洲一区二区久久久久久久| 久色乳综合思思在线视频| 亚洲毛片在线观看| 国模精品系列视频| 亚洲人成77777在线观看网| 国产三级精品网站| 国产精品久久久久免费a∨| 九九精品在线播放| 欧美成人午夜影院| 欧美xxxx做受欧美| 国产精品午夜一区二区欲梦| xxx一区二区| 国产亚洲一区二区精品| 亚洲精品wwww| 久久人人爽人人爽人人片亚洲| 亚洲国产欧美久久| 日韩亚洲一区二区| 在线观看不卡av| 亚洲男人7777| 最近2019中文字幕大全第二页| 成人在线精品视频| 97在线观看免费高清| 日韩欧美精品免费在线| 亚洲人午夜精品| 亚洲人成欧美中文字幕| 精品亚洲一区二区| 国产精品直播网红| 亚洲第一色中文字幕| 国产在线视频不卡| 欧美亚洲日本网站| 久久视频国产精品免费视频在线| 欧美诱惑福利视频| 国产综合色香蕉精品| 永久免费看mv网站入口亚洲| 亚洲成人久久久| 色99之美女主播在线视频| 国产欧美在线播放| 亚洲免费中文字幕| 欧美在线观看www| 亚洲一区二区三区四区在线播放| 欧美又大又硬又粗bbbbb| 久久久久国色av免费观看性色| 精品福利视频导航| 亚洲人成在线观| 精品国产一区二区三区久久| 精品五月天久久| 26uuu另类亚洲欧美日本老年| 欧美电影在线播放| 日本精品中文字幕| 高清日韩电视剧大全免费播放在线观看| 亚洲精品久久7777777| 欧美激情网友自拍| 中文在线资源观看视频网站免费不卡| 伊人久久免费视频| 国产精品视频在线观看| 精品国产91久久久久久老师| 亚洲福利小视频| 国产视频久久久| 欧美成人精品在线| 一区二区欧美久久| 亚洲自拍小视频免费观看| 欧美亚洲一区在线| 国产一区二区三区在线观看视频| 久久久电影免费观看完整版| 欧美精品久久一区二区| 777午夜精品福利在线观看| 日韩美女在线观看| 97国产精品久久| 国产美女久久精品| 久久青草福利网站| 丝袜亚洲欧美日韩综合| 欧美自拍视频在线观看| 日韩精品久久久久久久玫瑰园| 国产一区二区成人| 国产精品视频自在线| 日av在线播放中文不卡| 亚洲欧美日韩网| 欧美激情视频给我| 国产va免费精品高清在线| 日韩国产一区三区| 国产成人精品久久久| 午夜精品美女自拍福到在线| 国产精品亚洲精品| 欧美专区中文字幕| 日本不卡高字幕在线2019| 亚洲国产天堂久久综合| 亚洲无限乱码一二三四麻| 亚洲国产成人精品女人久久久| 亚洲www在线观看| 亚洲欧美激情一区| 国产精品一区二区av影院萌芽| 热草久综合在线| 欧美性xxxx极品hd欧美风情| 日韩成人中文电影| 国产98色在线| 国产精品久久久久久久久借妻| 日韩中文在线中文网在线观看| www国产91| 高清欧美性猛交| 国产精品jvid在线观看蜜臀| 91久久在线播放| 57pao成人国产永久免费| 亚洲精品在线看| 色av吧综合网| 理论片在线不卡免费观看| 亚洲女同精品视频| 国产欧美在线视频| 成人动漫网站在线观看| 欧美最猛性xxxxx(亚洲精品)| 国产免费一区二区三区在线观看| 亚洲国产高清自拍| 97免费中文视频在线观看| 国产精品视频公开费视频| 欧美精品一本久久男人的天堂| 欧美激情免费在线| 日韩精品视频在线免费观看| 久久精品国产成人精品| 日韩福利在线播放| 亚洲天堂成人在线| 亚洲免费小视频| 亚洲一品av免费观看| 久久久天堂国产精品女人| 国产美女精品视频| 国产精品美女视频网站| 98午夜经典影视| 中文字幕日本欧美| 欧美激情欧美狂野欧美精品| 97精品视频在线| 久久久亚洲国产天美传媒修理工| 欧美色视频日本高清在线观看| 欧美激情视频一区二区| 国产在线久久久| 成人黄色免费网站在线观看| 亚洲图片在线综合| 国产精品久久久久久久久借妻| 国产精品国产亚洲伊人久久| 欧美国产精品va在线观看| 国产999在线观看| 国产99视频精品免视看7| 午夜精品三级视频福利| 亚洲视频视频在线| 亚洲码在线观看| 欧美高清不卡在线| 欧美日韩国产精品一区二区不卡中文| 日韩**中文字幕毛片| 91免费精品国偷自产在线| 亲爱的老师9免费观看全集电视剧| 亚洲最大成人网色| 欧美猛交免费看| 92版电视剧仙鹤神针在线观看| 久久久久久尹人网香蕉| 国产日韩av在线播放| 亚洲欧美日韩一区二区在线| 日韩电影视频免费| 国产日韩在线看| 精品性高朝久久久久久久|