權限
路由權限
靜態路由:固定的路由,沒有權限。如login頁面
動態路由:根據不同的角色,后端返回不同的路由接口。通過meta中的roles去做篩選
store存儲路由
3 //地址:store/modules/permission
import { routes as constantRoutes } from '@/router' // 根據meta.roles去判斷該角色是否有路由權限 function hasPermission(roles, route) { if (route.meta && route.meta.roles) { return route.meta.roles.some(val => val === roles) } return true } /** * 遞歸動態路由 * @param routes 動態路由 * @param roles 角色 */ export function filterAsyncRoutes(routes, roles) { const res = [] routes.forEach(route => { const tmp = { ...route } if (hasPermission(roles, tmp)) { if (tmp.children) { //后臺傳來的路由字符串,轉換為組件對象 // let a = `../views/${route.component}`; // route.component = () => import(a); // 導入組件 tmp.children = filterAsyncRoutes(tmp.children, roles) } res.push(tmp) } }) return res } //模擬后端傳過來的路由 export const asyncRoutes = [ { path: '/', name: 'home', redirect: '/PickupTask', meta: { title: '首頁', //純前端去做動態路由 roles: ['admin'] }, component: () => import('@/views/HomeView.vue'), children: [ { path: 'PickupTask', name: 'PickupTask', meta: { title: 'PickupTask', }, component: () => import('@/views/Sd/PickupTask.vue'), }, { path: 'access', hidden: true, component: () => import('@/views/demo/Access.vue'), meta: { title: 'access', roles: ['admin'], //按鈕權限標識 button: { 'btn:access:createUser': 'hidden', 'btn:access:editUser': 'disable' }, }, }, ], } ] const permisssion = { // namespaced: true, -> store.dispatch('permisssion/generateRoutes', 'admin'); state: { //靜態路由+動態路由 routes: [], //動態路由 addRoutes: [] }, mutations: { SET_ROUTES: (state, routes) => { state.addRoutes = routes state.routes = constantRoutes.concat(routes) } }, actions: { generateRoutes({ commit }, roles) { return new Promise(resolve => { let accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) commit('SET_ROUTES', accessedRoutes) resolve(accessedRoutes) }) } } } export default permisssion
router添加路由
將store中的動態路由使用addRoute添加(最新版本去掉了addRoutes只能使用addRoute添加路由)。
//地址:router/index import Vue from 'vue'; import VueRouter, { RouteConfig } from 'vue-router'; import store from '@/store'; Vue.use(VueRouter); const isProd = process.env.NODE_ENV === 'production'; const routerContext = require.context('./', true, /index.js$/); //靜態路由 export let routes: any = []; routerContext.keys().forEach((route) => { // route就是路徑 // 如果是根目錄的index不做處理 if (route.startsWith('./index')) { return; } const routerModule = routerContext(route); routes = [...routes, ...(routerModule.default || routerModule)]; }); // 創建 router 實例,然后傳 `routes` 配置 const router = new VueRouter({ mode: 'history', base: isProd ? '/vue-demo/' : process.env.BASE_URL, routes, scrollBehavior(to, from, savedPosition) { if (to.hash) { return { selector: to.hash, }; } }, }); let registerRouteFresh = true; /** * 全局全局前置守衛 * to : 將要進入的目標路由對象 * from : 即將離開的目標路由對象 */ router.beforeEach(async (to: any, from, next) => { //設置當前頁的title document.title = to.meta.title; if (to.path === '/login' && localStorage.getItem('token')) { next('/'); } console.log(registerRouteFresh); //如果首次或者刷新界面,next(...to, replace: true)會循環遍歷路由, //如果to找不到對應的路由那么他會再執行一次beforeEach((to, from, next))直到找到對應的路由, //我們的問題在于頁面刷新以后異步獲取數據,直接執行next()感覺路由添加了但是在next()之后執行的, //所以我們沒法導航到相應的界面。這里使用變量registerRouteFresh變量做記錄,直到找到相應的路由以后,把值設置為false然后走else執行next(),整個流程就走完了,路由也就添加完了。 if (registerRouteFresh) { //設置路由 const accessRoutes = await store.dispatch('generateRoutes', 'admin'); let errorPage = { path: '*', name: '404', component: () => import('../views/404.vue'), }; // 將404添加進去 // 現在才添加的原因是:作為一級路由,當刷新,動態路由還未加載,路由就已經做了匹配,找不到就跳到了404 router.addRoute({ ...errorPage }); accessRoutes.forEach((item: RouteConfig) => { router.addRoute(item); }); //獲取路由配置 console.log(router.getRoutes()); //通過next({...to, replace})解決刷新后路由失效的問題 next({ ...to, replace: true }); registerRouteFresh = false; } else { next(); } next(); }); export default router;
菜單權限
路由遍歷,通過store路由權限中的permission.state.routes去做處理
按鈕權限
準備:存儲按鈕標識
//地址:store/modules/user import { userInfo, } from '@/api' const user = { state: { role: 'admin', mockButton: { 'btn:access:createUser': 'show', 'btn:access:editUser': 'show' } }, //更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation mutations: { change_role: (state, data) => { state.role = data.role }, change_btn: (state, data) => { state.mockButton = data.mockButton } }, } export default user
指令
通過模擬傳入按鈕標識的屬性,去判斷按鈕是否隱藏或者禁用
//地址:directive/permission/index import permission from './permissionBtn' const install = function(Vue) { Vue.directive('permission', permission) } if (window.Vue) { window['permission'] = permission Vue.use(install); // eslint-disable-line } permission.install = install export default permission
//地址:directive/permission/permissionBtn import store from '@/store' function checkPermission(el, binding) { const { value } = binding const roles = store.getters && store.getters.role // 獲取模擬權限按鈕標識 const mockButton = store.getters && store.getters.mockButton // 設置按鈕屬性 if (mockButton[value] === 'disabled') { el.disabled = true el.setAttribute('disabled', true) } if (mockButton[value] === 'hidden') { el.style.display = 'none' } if (mockButton[value] === 'show') { el.style.display = 'block' el.disabled = false } // throw new Error(`need roles! Like v-permission="['admin','editor']"`) } export default { inserted(el, binding) { checkPermission(el, binding) }, update(el, binding) { checkPermission(el, binding) } }
//應用
<template> <div> <a-button @click="changeRole">切換角色</a-button> <span>當前角色:{{ role }}</span> <!-- 注意一定要加disabled屬性,才能設置它的disabled值 --> <a-button :disabled="false" v-permission="'btn:access:createUser'"> 新建用戶 </a-button> <a-button :disabled="false" v-permission="'btn:access:editUser'"> 編輯用戶 </a-button> </div> </template> <script> import { Vue, Component, Watch } from "vue-property-decorator"; import permission from "@/directive/permission/index.js"; // 權限判斷指令 // import checkPermission from '@/utils/permission' // 權限判斷函數 @Component({ directives: { permission, }, computed: { role() { return this.$store.getters.role; }, }, }) export default class Access extends Vue { get role() { return this.$store.getters.role; } changeRole() { //設置按鈕權限 this.$store.commit("change_btn", { mockButton: this.role === "admin" ? { "btn:access:createUser": "hidden", "btn:access:editUser": "disabled", } : { "btn:access:createUser": "show", "btn:access:editUser": "show", }, }); //設置角色 this.$store.commit("change_role", { role: this.role === "admin" ? "edit" : "admin", }); } } </script>
函數
/** * @param {Array} value * @returns {Boolean} * @example see @/views/permission/directive.vue * 除了使用指令,也可以使用函數 */ export default function checkPermission(value) { if (value && value instanceof Array && value.length > 0) { const roles = store.getters && store.getters.roles const permissionRoles = value const hasPermission = roles.some(role => { return permissionRoles.includes(role) }) return hasPermission } console.error(`need roles! Like v-permission="['admin','editor']"`) return false }
<template> <div> <a-button v-if="hasPerms('btn:access:createUser')" :disable="hasPerms('btn:access:createUser')" > 新建用戶 </a-button> <a-button v-if="hasPerms('btn:access:editUser')" :disable="hasPerms('btn:access:editUser')" > 編輯用戶 </a-button> </div> </template> <script> import { Vue, Component, Watch } from "vue-property-decorator"; import checkPermission from "@/utils/permission"; // 權限判斷函數 @Component export default class Access extends Vue { hasPerms(params) { return checkPermission(params); } } </script>
內容已講述完畢,希望大家有收獲。歡迎閱讀更多相關內容。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/127835.html
摘要:五六月份推薦集合查看最新的請點擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...
摘要:五六月份推薦集合查看最新的請點擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...
摘要:目前的技術棧主要的采用由于是個人項目,所以數據請求都是用了代替。后續會出一系列的教程配套文章,如如何從零構建后臺項目框架,如何做完整的用戶系統如權限驗證,二次登錄等,如何二次開發組件如富文本,如何整合七牛等等文章,各種后臺開發經驗等等。 完整項目地址:vue-element-admin系類文章一:手摸手,帶你用vue擼后臺 系列一(基礎篇)系類文章二:手摸手,帶你用vue擼后臺 系列二...
摘要:一前言提綱基于和框架寫的一個全棧購物商城,記錄項目過程中遇到的一些問題以及經驗和技巧。服務端技術棧登錄授權用認證機制,來實現登錄登出。服務器配置和緩存策略,根據不同的來代理。申請證書全站升級到,配置的協議。一、前言提綱 基于Vue和Express框架寫的一個全棧購物商城,記錄項目過程中遇到的一些問題以及經驗和技巧。 二、歷史版本 基于Vue-CLI2.0:點我查看 這個分支版本是一兩年前...
閱讀 547·2023-03-27 18:33
閱讀 732·2023-03-26 17:27
閱讀 630·2023-03-26 17:14
閱讀 591·2023-03-17 21:13
閱讀 521·2023-03-17 08:28
閱讀 1801·2023-02-27 22:32
閱讀 1292·2023-02-27 22:27
閱讀 2178·2023-01-20 08:28