在開發后台管理項目時,多用戶多角色不同權限的場景可以說是非常普遍的。從零開始手寫一個后台,要考慮的東西很多,這里直接拿網上大家比較熟悉的vue-admin-template后台模版來進行改造。
先來看下vue-admin-template這個模版的代碼目錄結構
├── build # 構建相關 ├── mock # 項目mock 模擬數據 ├── public # 靜態資源 │ │── favicon.ico # favicon圖標 │ └── index.html # html模板 ├── src # 源代碼 │ ├── api # 所有請求 │ ├── assets # 主題 字體等靜態資源 │ ├── components # 全局公用組件 │ ├── icons # 項目所有 svg icons │ ├── layout # 全局 layout │ ├── router # 路由 │ ├── store # 全局 store管理 │ ├── styles # 全局樣式 │ ├── utils # 全局公用方法 │ ├── views # views 所有頁面 │ ├── App.vue # 入口頁面 │ ├── main.js # 入口文件 加載組件 初始化等 │ └── permission.js # 權限管理 ├── tests # 測試 ├── .env.xxx # 環境變量配置 ├── .eslintrc.js # eslint 配置項 ├── .babelrc # babel-loader 配置 ├── .travis.yml # 自動化CI配置 ├── vue.config.js # vue-cli 配置 ├── postcss.config.js # postcss 配置 └── package.json # package.json
login.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png
比如我們用財務這個用戶去登錄一下后台,(先給財務這個角色分配一下權限)

image.png
比如給他分配
培訓認證全部的權限

image.png
然后管理員登錄后台,只渲染所擁有的權限動態渲染了側邊欄。

image.png
補充一下:這里是按鈕權限的設置,全局配置一個指令,到時候
v-permission='['add']'
就可以實現按鈕是否顯示。

image.png
基本上就是這么個東西,先添加菜單
,在新建一個角色
,再給這個角色分配一下權限
,然后在新建個用戶
,賬號密碼配置一下,再給這個用戶分配一個角色
,最后這個用戶登錄后台,就展示所擁有的權限
,動態去渲染側邊欄
第二步 : 我們先來啟動一下vue-admin-template這個模版,安裝依賴 cnpm install
啟動:npm run dev

image.png

image.png
可以看到,全是英文的,我是受不了,(英文爛的一逼,看不懂),側邊欄是手寫的英文,刪掉就好了,element-ui 是英文的,這個要改一下配置。
修改路徑 src/main.js // Vue.use(ElementUI, { locale }) // 如果想要中文版 element-ui,按如下方式聲明 Vue.use(ElementUI) 😄
當然要先實現正常登錄,我這里用下真實的登錄接口,修改一下src/api/user.js

image.png
.env.development

image.png
vue.config.js
配置反向代理,然后重啟項目

image.png
箭頭標注的根據實際情況修改

image.png
這樣實際是觸發登錄接口了,為啥沒登錄進去呢,因為登錄成功后,會立即觸發getinfo 這個接口,這個接口請求出錯,就會清除token且又回到登錄頁了。
所以接下來要完善getinfo這個接口,先來看下邏輯
1.執行完登錄請求后,會走 permission.js
中的邏輯

image.png
可以看到getinfo,所以就要完善getinfo這個接口,同樣換成真實的。

image.png
store/modules/user.js
根據實際情況修改下getinfo這個方法,這里看自己公司要求,我們只是取到昵稱和頭像存起來,也可以在這個方法直接把該用戶所擁有的權限拿到並保存到vuex,建議在起一個接口,模擬的話我先在這個方法里把路由信息寫死,然后在定一個存儲到vuex的方法
const getDefaultState = () => { return { token: getToken(), name: '', avatar: '', menus: "",//新增 } } const mutations = { RESET_STATE: (state) => { Object.assign(state, getDefaultState()) }, SET_TOKEN: (state, token) => { state.token = token }, SET_NAME: (state, name) => { state.name = name }, SET_AVATAR: (state, avatar) => { state.avatar = avatar }, // 新增 SET_MENUS: (state, menus) => { state.menus = menus } } // get user info getInfo({ commit, state }) { return new Promise((resolve, reject) => { getInfo().then(response => { //用戶信息是根據token返回的, //我們把token放到header里自動帶過去了,這里就把state.token刪掉了 const { data } = response if (!data) { return reject('Verification failed, please Login again.') } const { nickname, avatar } = data // 模擬請求數據 const menus = [ { "path": "/system", "redirect": "/menu", "component": "Layout", "meta": { "title": "系統管理", "icon": "form" }, "children": [{ "path": "/menu", "name": "menu", "component": "menu/index", "meta": { "title": "菜單管理", "icon": "table", } }, { "path": "/roles", "name": "roles", "component": "roles/index", "meta": { "title": "角色管理", "icon": "table", } }, { "path": "/administrator", "name": "administrator", "component": "dashboard/index",