<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
//地址: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
將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 lang='ts'> 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 lang='ts'> 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>
到此這篇關於vue2模擬vue-element-admin手寫角色許可權的實現的文章就介紹到這了,更多相關vue2 角色許可權內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45