項目demo展示


重要功能總結
權限功能的實現
權限路由思路:


根據用戶登錄的roles信息與路由中配置的roles信息進行比較過濾,生成可" />

vue實現后臺管理權限系統及頂欄三級菜單顯示功能

 更新時間:2019-06-21 18:04:47   作者:佚名   我要評論(0)

•效果演示地址
項目demo展示


重要功能總結
權限功能的實現
權限路由思路:


根據用戶登錄的roles信息與路由中配置的roles信息進行比較過濾,生成可

•效果演示地址

項目demo展示

重要功能總結

權限功能的實現

權限路由思路:

 根據用戶登錄的roles信息與路由中配置的roles信息進行比較過濾,生成可以訪問的路由表,并通過router.addRoutes(store.getters.addRouters)動態添加可訪問權限路由表,從而實現左側和頂欄菜單的展示。

實現步驟:

1.在router/index.js中,給相應的菜單設置默認的roles信息;

如下:給"權限設置"菜單設置的權限為:meta:{roles: ['admin', 'editor']},及不同的角色都可以看到; 給其子菜單"頁面權限",設置權限為:meta:{roles: ['admin']},及表示只有"admin"可以看到該菜單; 給其子菜單"按鈕權限"設置權限為:meta:{roles: ['editor']},及表示只有"editor"可以看到該菜單。

2.通過router.beforeEach()和router.afterEach()進行路由過濾和權限攔截;

代碼如下:

// permission judge function
function hasPermission(roles, permissionRoles) {
 if (roles.indexOf('admin') >= 0) return true // admin permission passed directly
 if (!permissionRoles) return true
 return roles.some(role => permissionRoles.indexOf(role) >= 0)
}
const whiteList = ['/login'] // 不重定向白名單

router.beforeEach((to, from, next) => {
 NProgress.start()
 // 設置瀏覽器頭部標題
 const browserHeaderTitle = to.meta.title
 store.commit('SET_BROWSERHEADERTITLE', {
 browserHeaderTitle: browserHeaderTitle
 })
 // 點擊登錄時,拿到了token并存入了vuex;
 if (getToken()) {
 /* has token*/
 if (store.getters.isLock && to.path !== '/lock') {
 next({
 path: '/lock'
 })
 NProgress.done()
 } else if (to.path === '/login') {
 next({ path: '/' }) // 會匹配到path:'',后面的path:'*'還沒有生成;
 NProgress.done() 
 } else {
 if (store.getters.roles.length === 0) {
 store.dispatch('GetInfo').then(res => { // 拉取用戶信息
  const roles = res.roles
  store.dispatch('GenerateRoutes', { roles }).then(() => { // 根據roles權限生成可訪問的路由表
  router.addRoutes(store.getters.addRouters) // 動態添加可訪問權限路由表
  next({ ...to, replace: true }) // hack方法 確保addRoutes已完成
  })
 }).catch((err) => {
  store.dispatch('FedLogOut').then(() => {
  Message.error(err || 'Verification failed, please login again')
  next({ path: '/' })
  })
 })
 } else {
 // 沒有動態改變權限的需求可直接next() 刪除下方權限判斷 ↓
 if (hasPermission(store.getters.roles, to.meta.roles)) {
  next()//
 } else {
  next({ path: '/401', replace: true, query: { noGoBack: true }})
 }
 }
 }
 } else {
 if (whiteList.indexOf(to.path) !== -1) {
 next()
 } else {
 // 點擊退出時,會定位到這里
 next('/login')
 NProgress.done()
 }
 }
})

router.afterEach(() => {
 NProgress.done() // 結束Progress
 setTimeout(() => {
 const browserHeaderTitle = store.getters.browserHeaderTitle
 setTitle(browserHeaderTitle)
 }, 0)
})

用戶點擊登錄之后的業務邏輯分析:

1、用戶調取登錄接口,獲取到token,進行路由跳轉到首頁;

2、通過路由導航鉤子router.beforeEach((to,from,next)=>{})函數確定下一步的跳轉邏輯,如下:
2.1、用戶已經登錄成功并返回token值;

 2.1.1、lock 鎖屏場景; 

 2.1.2、用戶重新定位到登錄頁面; 

  2.1.3、根據用戶是否有roles信息,進行不同的業務邏輯,如下:  

    (1)、初始情況下,用戶roles信息為空;

        通過store.dispatch('GetInfo')調取接口,獲取用戶信息;
        獲取到roles信息后,將roles,name,avatar保存到vuex;
        同時,通過store.dispatch('GenerateRoutes', { roles })去重新過濾和生成路由,并將重新生成之后的權限路由'routes'保存到vuex;
        最后,通過router.addRoutes()合并路由表;  
        如果在獲取用戶信息接口時,出現錯誤,則調取store.dispatch('FedLogOut')接口,返回到login頁面;
        用戶FedLogOut之后,需要情況vuex和localStorage中的token信息;         

   (2)、用戶已經擁有roles信息;

        點擊頁面路由,通過roles權限判斷 hasPermission();
        如果用戶有該路由權限,直接跳轉對應的頁面;如果沒有權限,則跳轉至401提示頁面;

2.2、用戶沒有獲取到token值;

  2.2.1、如果設置了白名單用戶,則直接跳轉到相應的頁面;反之,則跳轉至登錄頁面; 

3、通過路由導航鉤子函數router.afterEach(() => {}),做收尾工作,如下:
3.1、NProgress.done() // 結束Progress
3.2、獲取到title并設置title;

詳細代碼,請參考src/permission.js

4、權限演示說明

測試賬號:

(1). username: admin,password: 123456;admin擁有最高權限,可以查看所有的頁面和按鈕;

(2). username: editor,password: 123456;editor只有被賦予權限的頁面和按鈕才可以看到;

三級導航菜單頂部欄展示

如圖所示,在完成一般后臺系統所具有的二級導航菜單功能之后,我發現其實很多的后臺管理系統都有三級導航菜單,但是如果都把三級菜單放到左側菜單做階梯狀排列,就會顯得比較緊湊,因此我覺得把所有的三級菜單放到頂部是一個不錯的選擇。

開發需求:點擊左側菜單,找到其對應的菜單(頂欄菜單)排放于頂部導航欄;

開發步驟:

1、 定義頂部導航組件topMenu.vue;

通過element-ui,NavMenu 導航菜單來進行頂部菜單的展示,注意頂欄和側欄設置的區別;同時將其引用于頭部組件headNav.vue中;

2、定義頂欄路由數據router/topRouter.js;

格式如下:

export const topRouterMap = [
 {
 'parentName':'infoShow',
 'topmenulist':[
  {
  path: 'infoShow1',
  name: 'infoShow1',
  meta: {
   title: '個人信息子菜單1',
   icon: 'fa-asterisk',
   routerType: 'topmenu'
  },
  component: () => import('@/page/fundList/moneyData')
  }
 ]
 },
 {
 'parentName':'chinaTabsList',
 'topmenulist':[
  {
  path:'chinaTabsList1',
  name:'chinaTabsList1',
  meta:{
   title:'區域投資子菜單1',
   icon:'fa-asterisk',
   routerType:'topmenu'
  },
  component: () => import('@/page/fundList/moneyData')
  }
 ]
 }
]

定義topRouterMap為路由總數組;通過parentName來與左側路由建立聯系;通過topmenulist表示該頂欄路由的值;通過meta.routerType的值為"topmenu"或"leftmenu"來區分是頂欄路由,還是左側路由;

3、 準備headNav.vue中渲染數據;

思路:點擊左側菜單,需要顯示頂部對應的菜單。因為左側菜單要和頂部菜單建立聯系。我們知道導航菜單在用戶登錄時,會根據用戶的role信息進行權限過濾;那么,在過濾權限路由數據之前,我們可以通過addTopRouter()將所有的三級菜單進行過濾添加,添加完成之后,繼續進行角色過濾,可以保證將不具備權限的頂部菜單也過濾掉。

// 通過循環過濾,生成新的二級菜單
function addTopRouter(){
 asyncRouterMap.forEach( (item) => {
 if(item.children && item.children.length >= 1){
 item.children.forEach((sitem) => {
 topRouterMap.forEach((citem) => {
  if(sitem.name === citem.parentName){
  let newChildren = item.children.concat(citem.topmenulist);
  item.children = newChildren;
  }
 })
 })
 }
 })
 return asyncRouterMap;
}

4、點擊左側菜單過濾路由并顯示對應數據;

在組件topMenu.vue中,用戶默認進來或者點擊左側菜單,觸發setLeftInnerMenu()函數,如下:

 setLeftInnerMenu(){
 if(this.$route.meta.routerType == 'leftmenu'){ // 點擊的為 左側的2級菜單
 this.$store.dispatch(''ClickLeftInnerMenu,
  {'name':this.$route.name}
 );
 }else{ // 點擊頂部的菜單
 this.$store.dispatch('ClickTopMenu',
  {'title':this.$route.meta.title}
 );
 }
}

通過當前路由this.$route.meta.routerType的值判斷,用戶是點擊頂部菜單還是左側菜單。如果點擊頂部菜單,通過this.$store觸發異步動作'ClickLeftInnerMenu'并傳遞參數'name',vuex中通過state.topRouters = filterTopRouters(state.routers,data)過濾當前路由信息;代碼如下:

// 獲取到當前路由對應頂部子菜單
 function filterTopRouters(data){
 let topRouters = topRouterMap.find((item)=>{
 return item.parentName === data.name
 })
 if(!mutils.isEmpty(topRouters)){
 return topRouters.topmenulist;
 }
}

topMenu.vue中,通過 computed:{ ...mapGetters(['topRouters'])}進行對應頂部路由數據的展示。用戶每次點擊左側菜單時,頂部路由都進行了重新賦值并渲染,保證了數據的準確性。

5、頂部菜單完善;

當頂部菜單的數據量過大時,我們需要設置橫向滾動條并設置滾動條的樣式。
 如圖:

mock數據詳解

easy-mock使用

Easy Mock介紹:

•Easy Mock 是一個可視化,并且能快速生成 模擬數據 的持久化服務,
•Easy Mock 支持基于 Swagger 創建項目,以節省手動創建接口的時間;
•簡單點說:Easy Mock就是一個在線創建mock的服務平臺,幫你省去你 配置、安裝、起服務、維護、多人協作Mock數據不互通等一系列繁瑣的操作, 它能在不用1秒鐘的時間內給你所要的一切。

詳細使用方法,包含新建項目,基礎語法,數據占位符,Swagger等介紹和使用,請參考詳細文檔

easy-mock,在本項目中的使用:

1.按照官方文檔,創建個人項目vue-touzi-admin;

根據項目需要,創建的接口有:用戶登錄接口:"/user/login";獲取用戶信息接口:"/user/info";用戶登出接口:"/user/logout";獲取所有用戶列表接口:"/user/getUserList";如圖:

登錄接口在easy-mock端編寫的邏輯如下:

{
 code: function({
 _req
 }) {
 if (_req.body.username === "admin" || _req.body.username === "editor" && _req.body.password === "123456") {
 return 200
 } else {
 return -1
 }
 },
 message: function({
 _req
 }) {
 if (_req.body.username !== "admin" || _req.body.username !== "editor") {
 return "賬號或密碼有誤!"
 }
 },
 data: function({
 _req
 }) {
 if (_req.body.username == "admin" && _req.body.password === "123456") {
 return {
 code: 0,
 roles: ['admin'],
 token: 'admin',
 introduction: '我是超級管理員',
 name: 'Super Admin'
 }
 } else if (_req.body.username === 'editor' && _req.body.password === "123456") {
 return {
 code: 0,
 roles: ['editor'],
 token: 'editor',
 introduction: '我是編輯',
 name: 'Normal Editor'
 }
 } else {
 return "賬號或密碼有誤!"
 }
 }
}

1.webpack中,開發環境和生產環境地址配置;生產環境,NODE_ENV: '"production"';如下:

module.exports = merge(prodEnv, {
 NODE_ENV: '"development"',
 API_BASE_URL: '"https://easy-mock.com/mock/5cd03667adb0973be6a3d8d1/api"',
})

3.接口封裝實例;如下:

import request from '@/utils/axios'
export function login(username, password) {
 return request({
 url: process.env.API_BASE_URL+'/user/login',
 method: 'post',
 data: {
 username,
 password
 }
 })
}

mockjs使用

使用背景:

在使用easy-mock模擬數據的過程中,發現其對表格固定數據不能實現增刪改等功能,因而選擇了使用mockjs;

介紹及功能:

Mock.js是一款模擬數據生成器,旨在幫助前端攻城師獨立于后端進行開發,幫助編寫單元測試。提供了以下模擬功能:

1.根據數據模板生成模擬數據,通過mockjs提供的方法,你可以輕松地創造大量隨機的文本,數字,布爾值,日期,郵箱,鏈接,圖片,顏色等.

2.模擬 Ajax 請求,生成并返回模擬數據,mockjs可以進行強大的ajax攔截.能判斷請求類型,獲取到url,請求參數等.然后可以返回mock的假數據,或者你自己編好的json文件.功能強大易上手.

3.基于 HTML 模板生成模擬數據

mockjs在本項目中使用:

1.安裝mockjs

npm install mockjs --save-dev

2.創建mock文件夾結構并定義相關的功能模塊;如圖:

mockjs/index.js,負責定義相關的mock接口,如下:
import Mock from 'mockjs'
import tableAPI from './money'
// 設置全局延時 沒有延時的話有時候會檢測不到數據變化 建議保留
Mock.setup({
 timeout: '300-600'
})
// 資金相關
Mock.mock(/\/money\/get/, 'get', tableAPI.getMoneyList)
Mock.mock(/\/money\/remove/, 'get', tableAPI.deleteMoney)
Mock.mock(/\/money\/batchremove/, 'get', tableAPI.batchremoveMoney)
Mock.mock(/\/money\/add/, 'get', tableAPI.createMoney)
Mock.mock(/\/money\/edit/, 'get', tableAPI.updateMoney)

mockjs/money.js,則定義相關的函數,實現模擬數據的業務邏輯,比如資金流水數據的增刪改查等;數據的生成規則請參照mockjs官網文檔,上面有詳細的語法說明;

3.在main.js中引入定義好的mockjs;如下:

import './mockjs'  //引用mock

4.mockjs,api接口封裝;

src/api/money.js中,進行了統一的接口封裝,在頁面中調用對應函數,即可獲取到相應的模擬數據。代碼如下:

import request from '@/utils/axios'
export function getMoneyIncomePay(params) {
 return request({
 url: '/money/get',
 method: 'get',
 params: params
 })
}
export function addMoney(params) {
 return request({
 url: '/money/add',
 method: 'get',
 params: params
 })
}

5.組件中,接口調用,獲取數據,渲染頁面;

總結

以上所述是小編給大家介紹的vue實現后臺管理權限系統及頂欄三級菜單顯示功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

您可能感興趣的文章:

  • vue中如何實現后臺管理系統的權限控制的方法示例
  • 關于Vue的路由權限管理的示例代碼
  • 詳解VueJS應用中管理用戶權限
  • 動態加載權限管理模塊中的Vue組件
  • 基于vue實現網站前臺的權限管理(前后端分離實踐)
  • 詳解利用 Vue.js 實現前后端分離的RBAC角色權限管理
  • Vue iview-admin框架二級菜單改為三級菜單的方法

相關文章

最新評論

黑龙江新11选5开奖结果