Brief description
I recently wrote about vue control permissions (menu, route) projects, and used vuex and addRoutes to dynamically add routing methods, etc., with a total of more than 100 lines of code. I would like to share with you~
Logical combing
- Except for the login interface and the exit interface, the other interfaces are added token verification.
- When opening the page, a request is requested to obtain the menu interface. If the request is unsuccessful, it means that it is not logged in. The login page and * redirect are added to route by default.
- After logging in successfully, get the token and store the token in the session and request header.
- After logging in successfully, get the menu interface, match the requested route with all routes in vuex to obtain the component.
- Format the route that has obtained the component, find your own parentId, and insert it into the child of the element if found.
This is roughly the idea. It doesn’t matter if you hear something vaguely. Follow my steps to see how the code is written. You will understand~
accomplish
1. Initialization
import Vue from 'vue' import Router from 'vue-router' import store from '@/store' (Router) const router = new Router() // Global front guard( async (to, from, next) => { let userRoutes = //userRoutes Permissions The current user has if ( && !(item => == ).length) { next() return } next() }) export default router
You can see that there are no routes in it, because the routes are dynamically added, and there is only one global guard. The function is to manually enter the address in the user's address bar after logging in successfully to determine whether the route is correct. If it is correct, let him jump.
vuex
// export default { // All routes allRoutes: [ //Login page { path: '/demo', name: 'demo', component: () => import('@/views/demo') }, { path: '*', redirect: '/demo' }, //Main page { path: '/', component: () => import('@/views'), }, { path: '/home', name: 'home', component: () => import('@/views/home') } ], // The route that the user matches should be added to the route using addRoutes userRoutes: [], // Render the user menu userMenus: [] }
All routes need to be defined in the state, which is used to match the permissions requested by the background and obtain the component component.
There is the main logic inside, where the getMenu method is the core of this article
Format when data is returned menu = [ {id: 1, name: 'front page', path: '/home', parentId: 0}, {id: 2, name: 'System Settings', path: '', parentId: 0}, {id: 3, name: 'Role Configuration', path: '/roles', parentId: 2}, {id: 4, name: 'User Configuration', path: '/users', parentId: 2} ] Need to be processed menu = [ {id: 1, name: 'front page', path: '/home', parentId: 0}, {id: 2, name: 'System Settings', path: '', parentId: 0, child: [ {id: 3, name: 'Role Configuration', path: '/roles', parentId: 2}, {id: 4, name: 'User Configuration', path: '/users', parentId: 2} ] }, ]
So below, recursion is needed to handle it↓
// // Get current user permissions getMenu: async ({ state, commit, dispatch }) => { //Request permissions owned by the current user let result = await axios('/api/menu/find') if ( > 0) { let userRoutes = (item => { = [] (res => { if ( == ) { = } }) }) let oneArr = [], anotherArr = [] //oneArr Level 1 routing AnotherArr Other level routing oneArr = (item => !) anotherArr = (item => ) (item => { (obj => { if ( == ) { //If it matches, it means that the parent is found and push it directly into the parent's child if (!(k => == ).length) { (item) } } else { //If not, it means that the route at this level has not been found. Go to the next level route to find the parent. Routing levels: level 1 route, level 2 route, level 3 route... dispatch('recurrArr', {arr: oneArr, items: item}) } }) }) commit('setState', {state: 'userRoutes', value: userRoutes}) commit('setState', {state: 'userMenus', value: oneArr}) return {code: 1, data: userRoutes} //Return after processing is completed oneArr is nested after recursive processing, userRoutes is obtained to render route by component. } else { return {code: 0} } }, // Recursively find your own parentId recurrArr: ({dispatch}, {arr, items}) => { if (!arr) { return } for(let i = 0; i < ; i ++ ){ let item = arr[i] if ( == ) { if (!(k => == ).length) { (items) } break; } else { dispatch('recurrArr', {arr: , items: items}) } } }
So far, the route and menu data have been processed, and the rest is to add addRoutes to the route route, so that the page can be redirected~
Let's go to log in:
// Log in login: async ({ commit, dispatch}, params) => { let result = await axios('/api/login', {params}) if( > 0) { // After logging in successfully, get the current user permission route let userRoutes = await dispatch('getMenu') if ( > 0) { // Add the requested route dynamically to route () // After the addition is completed, you can now jump to the homepage~ ('/home') } return {code: 1, data: } } else { () return {code: 0} } },
Now that your project is done, your project can perform normal login, jump, dynamic update routing and other operations~
but
Now the last step is missing, log out
Because in axios intercept, the exit interface will be called after the token fails
( response => { if ( === 200) { // Authentication failed if( === -1) { // Execute logout ('global/loginOut') } else { // If there is a token in the request header let token = if(token) { ('token', token) = token } } return (response) } else { return (response) } } )
That's why I mentioned the beginning: When I first opened the page, I would like to request the menu interface regardless of whether I had logged in or not.
If you are not logged in, the login interface will be called to set the default route for the route.
// Log out loginOut: async ({ state }) => { // Log out and clear the tokens in tokens and headers ('token') delete // Log out to dynamically add the login page and * redirect page let errRoutes = (item => == '*') ((res => errRoutes[0].redirect == )[0]) (errRoutes); !== '/demo' ? ("/demo") : null let result = await axios('/api/loginOut', {params: {userId: }}) if( !== 1) { ('Login interface exception') } },
So far, even if there is a project, it’s done~
This is the end of this article about Vue's example of simply implementing front-end permission control. For more related Vue front-end permission control content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!