年前完工了作了半年的鐵路後臺管理系統,系統總體業務比較複雜,這也是我到公司從 0 到 1 的 一個完整系統實踐,作這個系統過程當中踩了很多坑,也學到了不少。javascript
作完這個系統沒多久,緊接着又一個系統來了,沒及時總結,慚愧哈!其實咱們在作的後臺管理系統大多數基礎框架都同樣,後臺管理系統 主要的 是
角色權限管理
,按鈕權限管理
和菜單管理
, 其它的業務主要圍繞在這個基礎之上進行擴展,最終 構成了符合業務的後臺管理系統
.前端因爲我司的項目都是採用
Vue
技術棧,那麼該文章也是講解Vue 如何進行權限管理
進行講解。vue結尾有彩蛋哦!
任何一個後臺管理系統都是 首先從登陸開始,登陸後返回用戶基本信息,以及token。java
token
:存入sessionStronge / localStronge
中,而後加入到 封裝好的Axios
的 請求頭中,每次請求攜帶token.- 用戶基本信息
登陸成功後同時要作不少事情,具體業務具體對待。
後臺管理系統
登陸成功後會請求當前用戶的菜單權限接口,來獲取用戶的可訪問的路由(動態路由),獲取成功後,Vue Router
是不能直接使用的,必須得解析成符合Vue Router 可識別的格式
.ios
handleLogin() { this.$refs.loginForm.validate(valid => { if (valid) { this.loading = true; login(this.loginForm) .then(res => { if (res.code === 200) { // 存放token sessionStorage.setItem("tokens", res.data.token); // 觸發Vuex 來 加載 獲取當前用戶的菜單,並解析路由 store.dispatch("setMenuList"); this.$message({ message: "登陸成功", type: "success", duration: 1000 }); this.$router.replace({ path: "/dashboard" }); } }) .catch(() => { this.loading = false; }); } else { console.log("error submit!!"); return false; } }); }
登陸成功後,本文經過
Vuex
來獲取當前用戶菜單和解析路由的。 後端
store.dispatch("setMenuList");
api
/* * @Description: * @Author: ZhangXin * @Date: 2021-02-02 16:10:59 * @LastEditTime: 2021-02-23 23:03:30 * @LastEditors: ZhangXin */ // getMenu 解析後臺路由 import { getMenu } from '../../utils/getMenu' // 引入路由 和 靜態路由 import router, { constantRoutes } from '../../router/index' const state = { routerType: '', // 菜單路由 meunList: [] } const mutations = { SET_ROUTER_TYPE(state, type) { state.routerType = type }, SET_ROUTER_MENULIST(state, list) { // 靜態路由 + 動態路由 合併 完整路由 const array = constantRoutes.concat(list) state.meunList = array router.options.routes = array router.addRoutes([...array]) } } const actions = { setMenuList({ commit, state }) { // 接收返回來的 路由數組 return new Promise((resolve, reject) => { getMenu().then(res => { commit('SET_ROUTER_TYPE', '') commit('SET_ROUTER_MENULIST', res) resolve(res) }) }) } } export default { state, mutations, actions }
封裝好的解析後端返回來的路由,這塊主要是爲了在
Vuex
中使用。
/* * @Description: * @Author: ZhangXin * @Date: 2021-02-02 16:03:48 * @LastEditTime: 2021-02-23 23:09:02 * @LastEditors: ZhangXin */ import Layout from '@/layout' import {getUserAuthMenu} from '@/api/user' /** * @description: 解析後端返回來的菜單樹 * @param {*} data 後端返回來的路由樹 * @param {*} arr 菜單 * @return {*} */ function tree(data, arr) { data.forEach((datas, index) => { arr.push({ path: datas.path, name: datas.name, types: datas.types, hidden: datas.hidden == 'true' ? true : false, // 當時這塊踩坑了 component: datas.component === 'Layout' ? Layout : resolve => require([`@/views/${datas.component}.vue`], resolve), meta: { title: datas.meta.title, icon: datas.meta.icon, // 用來存放按鈕權限 button: datas.meta.button }, // redirect: datas.redirect, id: datas.id, // 子路由 children: [] }) if (datas.children) { const childArr = tree(datas.children, []) arr[index].children = childArr } }) return arr } /** * @description: 獲取當前登陸用戶的菜單 * @param {*} * @return {*} */ export function getMenu() { return new Promise(function (resolve, reject) { getUserAuthMenu().then(res => { if(res.code === 200){ const datas = res.data // 調用 tree 來解析後端返回來的樹 resolve(tree(datas, [])) } }) }) }
到此爲止,已經實現了
Vue 動態權限控制
,別高興的太早,哈哈,一刷新頁面,頁面就進入了404 頁面
。數組這是爲何呢 ?
由於存入Vuex
中的數據,一刷新頁面,就會清空,那麼固然找不到當前路由,就進入404 頁面了
.如何處理呢?
1、 能夠 將 靜態和 動態 構成的完整路由 存放在
sessionStronge / localStronge
中,而後頁面刷新時,經過在 全局入口文件App.vue
的 生命週期 created 中 ,將router = sessionStronge / localStronge
存入的完整的路由,頁面在刷新時,它會從新加載完整的路由。 session2、若是是使用
Vuex
來獲取和解析用戶菜單的話, 那麼你能夠在全局入口文件App.vue
的 生命週期 created 中 ,再次執行Vuex Action
來從新加載用戶菜單app我這塊直接在
App.vue
的 生命週期created
中 , 再次執行了Vuex
來進行加載和解析,沒有作其它操做。 固然了,具體業務具體對待。
<template> <div id="app"> <router-view v-if="isRouterAlive" /> </div> </template> <script> import store from "@/store"; export default { name: "App", provide() { return { reload: this.reload }; }, data() { return { isRouterAlive: true }; }, methods: { reload() { this.isRouterAlive = false; this.$nextTick(() => (this.isRouterAlive = true)); } }, created() { //只要刷新頁面,就會從新加載路由樹,保證了路由不會丟失數據 store.dispatch("setMenuList"); } }; </script>
核心思想
- 1.定義符合 當前項目業務路由格式,先後端按這個接收傳遞
- 2.前端解析後端返回的動態路由,生成
Vue Router
可識別格式,最後拼接完整路由- 3.刷新路由丟失處理
<br/>
按鈕權限控制
- 1.當前組件 路由 攜帶可以使用的 按鈕權限,存入數組中,經過v-if 來判斷是否顯示
- 2.登陸時,單獨獲取整個系統的按鈕權限,將獲取到的全部按鈕 存入一個數組中,放入全局中,而後,經過 v-if 來判斷是否顯示
- 3. ............
❤️關注+點贊+收藏+評論+轉發❤️,原創不易,鼓勵筆者創做更好的文章