Permissions
Routing permissions
- Static routing: Fixed routing, no permissions. like login page
- Dynamic routing: The backend returns different routing interfaces according to different roles. Filter through roles in meta
Store storage routing
//Address: store/modules/permissionimport { routes as constantRoutes } from '@/router' // Determine whether the role has routing permissions based onfunction hasPermission(roles, route) { if ( && ) { return (val => val === roles) } return true } /** * Recursive dynamic routing * @param routes Dynamic routing * @param roles */ export function filterAsyncRoutes(routes, roles) { const res = [] (route => { const tmp = { ...route } if (hasPermission(roles, tmp)) { if () { //The route string passed from the background is converted into component object // let a = `../views/${}`; // = () => import(a); // Import component = filterAsyncRoutes(, roles) } (tmp) } }) return res } //Simulate the route transmitted from the backendexport const asyncRoutes = [ { path: '/', name: 'home', redirect: '/PickupTask', meta: { title: 'front page', //Pure front-end to do dynamic routing roles: ['admin'] }, component: () => import('@/views/'), children: [ { path: 'PickupTask', name: 'PickupTask', meta: { title: 'PickupTask', }, component: () => import('@/views/Sd/'), }, { path: 'access', hidden: true, component: () => import('@/views/demo/'), meta: { title: 'access', roles: ['admin'], //Button permission identification button: { 'btn:access:createUser': 'hidden', 'btn:access:editUser': 'disable' }, }, }, ], } ] const permisssion = { // namespaced: true, -> ('permisssion/generateRoutes', 'admin'); state: { // Static routing + dynamic routing routes: [], //Dynamic routing addRoutes: [] }, mutations: { SET_ROUTES: (state, routes) => { = routes = (routes) } }, actions: { generateRoutes({ commit }, roles) { return new Promise(resolve => { let accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) commit('SET_ROUTES', accessedRoutes) resolve(accessedRoutes) }) } } } export default permisssion
router add route
Add dynamic routes in the store using addRoute(The latest version has removed addRoutes and can only add routes using addRoute.)。
//Address: router/indeximport Vue from 'vue'; import VueRouter, { RouteConfig } from 'vue-router'; import store from '@/store'; (VueRouter); const isProd = .NODE_ENV === 'production'; const routerContext = ('./', true, /$/); // Static routingexport let routes: any = []; ().forEach((route) => { // route is the path // If it is the index in the root directory, it will not be processed if (('./index')) { return; } const routerModule = routerContext(route); routes = [...routes, ...( || routerModule)]; }); // Create a router instance and pass the `routes` configurationconst router = new VueRouter({ mode: 'history', base: isProd ? '/vue-demo/' : .BASE_URL, routes, scrollBehavior(to, from, savedPosition) { if () { return { selector: , }; } }, }); let registerRouteFresh = true; /** * Global front guard * to : The target routing object to be entered * from : The target routing object that is about to leave */ (async (to: any, from, next) => { //Set the title of the current page = ; if ( === '/login' && ('token')) { next('/'); } (registerRouteFresh); //If the interface is refreshed for the first time, next(...to, replace: true) will loop over the route. //If to cannot find the corresponding route, then it will execute beforeEach((to, from, next)) again until the corresponding route is found. //Our problem is that after the page is refreshed, the data is obtained asynchronously, and the next() is directly executed. It feels like the route is added but is executed after next(). //So we can't navigate to the corresponding interface. Here we use the variable registerRouteFresh variable to make records until the corresponding route is found, set the value to false and then go else to execute next(). The whole process is completed and the route is added. if (registerRouteFresh) { //Set up the route const accessRoutes = await ('generateRoutes', 'admin'); let errorPage = { path: '*', name: '404', component: () => import('../views/'), }; // Add 404 to // The reason I have only added now is: As a first-level route, when refreshed, the dynamic route has not yet loaded, the route has already matched, and if it cannot be found, it will jump to 404 ({ ...errorPage }); ((item: RouteConfig) => { (item); }); //Get routing configuration (()); //Solve the problem of route failure after refresh through next({...to, replace}) next({ ...to, replace: true }); registerRouteFresh = false; } else { next(); } next(); }); export default router;
Menu permissions
Routing traversal, processing through the store routing permissions
Button permissions
Preparation: Store button logo
//Address: store/modules/userimport { userInfo, } from '@/api' const user = { state: { role: 'admin', mockButton: { 'btn:access:createUser': 'show', 'btn:access:editUser': 'show' } }, //The only way to change the state in Vuex store is to submit the mutation mutations: { change_role: (state, data) => { = }, change_btn: (state, data) => { = } }, } export default user
instruction
By simulating the attributes identified by the incoming button, we can determine whether the button is hidden or disabled
//Address: directive/permission/indeximport permission from './permissionBtn' const install = function(Vue) { ('permission', permission) } if () { window['permission'] = permission (install); // eslint-disable-line } = install export default permission
//Address: directive/permission/permissionBtnimport store from '@/store' function checkPermission(el, binding) { const { value } = binding const roles = && // Get the simulated permission button identification const mockButton = && // Set button properties if (mockButton[value] === 'disabled') { = true ('disabled', true) } if (mockButton[value] === 'hidden') { = 'none' } if (mockButton[value] === 'show') { = 'block' = 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) } }
//application
<template> <div> <a-button @click="changeRole">Switch roles</a-button> <span>Current role:{{ role }}</span> <!-- Be sure to adddisabledproperty,Only set itdisabledvalue --> <a-button :disabled="false" v-permission="'btn:access:createUser'"> Create a new user </a-button> <a-button :disabled="false" v-permission="'btn:access:editUser'"> Edit user </a-button> </div> </template> <script lang='ts'> import { Vue, Component, Watch } from "vue-property-decorator"; import permission from "@/directive/permission/"; // Permission judgment command// import checkPermission from '@/utils/permission' // permission judgment function@Component({ directives: { permission, }, computed: { role() { return this.$; }, }, }) export default class Access extends Vue { get role() { return this.$; } changeRole() { //Set button permissions this.$("change_btn", { mockButton: === "admin" ? { "btn:access:createUser": "hidden", "btn:access:editUser": "disabled", } : { "btn:access:createUser": "show", "btn:access:editUser": "show", }, }); //Set role this.$("change_role", { role: === "admin" ? "edit" : "admin", }); } } </script>
function
/** * @param {Array} value * @returns {Boolean} * @example see @/views/permission/ * In addition to using instructions, you can also use functions */ export default function checkPermission(value) { if (value && value instanceof Array && > 0) { const roles = && const permissionRoles = value const hasPermission = (role => { return (role) }) return hasPermission } (`need roles! Like v-permission="['admin','editor']"`) return false }
<template> <div> <a-button v-if="hasPerms('btn:access:createUser')" :disable="hasPerms('btn:access:createUser')" > Create a new user </a-button> <a-button v-if="hasPerms('btn:access:editUser')" :disable="hasPerms('btn:access:editUser')" > Edit user </a-button> </div> </template> <script lang='ts'> import { Vue, Component, Watch } from "vue-property-decorator"; import checkPermission from "@/utils/permission"; // Permission judgment function@Component export default class Access extends Vue { hasPerms(params) { return checkPermission(params); } } </script>
This is the article about the implementation of vue2 simulated vue-element-admin handwritten role permissions. For more related vue2 role permissions, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!