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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM