Implementation of vue menu level permission control

I wrote an article "Vue Button Level Permission Control Implementation" , which introduced the front-end page's control of button permissions. This article talks about the front-end page's control of menu permissions.

The front-end menu authority is to control the display and hiding of the menu according to the user's authority. Different scenarios have different implementation methods.

One, front-end control routing

The front end configures a set of general routing tables and a set of dynamic routing tables, and then obtains user permission data, compares the dynamic routing table according to the permission data, generates a new routing table with user permissions, and then uses the router.addRoutes method to dynamically mount the new routing table Go to the router, and finally render the menu according to the routing table.

The implementation is as follows:
1. Configure general routing (404, login, etc.) in route.js.

import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);
const router = new Router({
    
    
  mode: 'hash',
  routes:[{
    
    
  		path:'/',
		redirect:'/login'
  },{
    
    
		path:'/login',
		name:'login',
		component: () => import('../view/login')
	},{
    
    
		path:'/404',
		name:'404',
		component: () => import('../view/404')
	}]
})
export default router;

2. Create a new routerList.js file and configure the dynamic routing table in it; control the display and hide of the menu through the isShow field.

const routerList = [{
    
    
		path:'/',
		name:'home',
		component: () => import('../view/index.vue'),
		meta:{
    
    
			title:'Home'
		},
		children:[{
    
    
			path:'menu1',
			name:'menu1',
			isShow:true,
			component: () => import('../view/menu1.vue'),
			meta:{
    
    
				title:'菜单1',
				icon:'el-icon-info'
			}
		},{
    
    
			path:'menu2',
			name:'menu2',
			isShow:true,
			component: () => import('../view/menu2.vue'),
			meta:{
    
    
				title:'菜单2',
				icon:'el-icon-info'
			}
		},{
    
    
			path:'menu3',
			name:'menu3',
			isShow:true,
			component: () => import('../view/menu3.vue'),
			meta:{
    
    
				title:'菜单3',
				icon:'el-icon-info'
			}
		}]	
	}
]

3. The access interface returns permission data.

//以数组为例
['menu1','menu3']

4. Process the existing dynamic routing table according to this array, change the isShow attribute value of the route in the dynamic routing table corresponding to the menu that is not in the array to false; save the generated new routing table to vuex and localStorage.

const routerList = [{
    
    
		path:'/',
		name:'home',
		component: () => import('../view/index.vue'),
		meta:{
    
    
			title:'Home'
		},
		children:[{
    
    
			path:'menu1',
			name:'menu1',
			isShow:true,
			component: () => import('../view/menu1.vue'),
			meta:{
    
    
				title:'菜单1',
				icon:'el-icon-info'
			}
		},{
    
    
			path:'menu2',
			name:'menu2',
			isShow:false,
			component: () => import('../view/menu2.vue'),
			meta:{
    
    
				title:'菜单2',
				icon:'el-icon-info'
			}
		},{
    
    
			path:'menu3',
			name:'menu3',
			isShow:true,
			component: () => import('../view/menu3.vue'),
			meta:{
    
    
				title:'菜单3',
				icon:'el-icon-info'
			}
		}]	
	}
]

4. In the created life cycle of the App.vue file, use the addRouters method to add the latest routing table processed by the permission data to the router.

//处理好数据之后
this.$router.options.routes = routerList;
this.$router.addRoutes(routerList);

5. When the route is switched, use the route guard to determine whether the page currently to be jumped has the authority, if there is a normal jump, if there is no jump to the 404 page.

router.beforeEach((to, from, next) => {
    
    
  if (to.path === '/login') {
    
    
    next();
  } else if (to.path === '/404') {
    
    
      next();
  } else {
    
    
        let resstr = ['menu1','menu3'];
        if (resstr != 'null' && resstr != undefined) {
    
    
          let hasPermiss = resstr.find(item => {
    
    
              return item.includes(to.path.split('/')[to.path.split('/').length-1]);
          })
          if (hasPermiss) {
    
    
            next();
          } else {
    
    
            next({
    
    path: '/404'});
          }
        }
    }
})

6. On the menu page, use this.$router.options.routers to obtain the latest routing object, and render the menu bar through the v-for loop. The menu with the isShow attribute value of false is not displayed.

Two, back-end control routing

The routing table is maintained by the back-end, and the data is obtained through the interface front-end, and then added to the router using the addRoutes method, and finally the menu is rendered according to the routing table.

The implementation is as follows:
1. Configure general routing (404, login, etc.) in route.js.

import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);
const router = new Router({
    
    
  mode: 'hash',
  routes:[{
    
    
  		path:'/',
		redirect:'/login'
  },{
    
    
		path:'/login',
		name:'login',
		component: () => import('../view/login')
	},{
    
    
		path:'/404',
		name:'404',
		component: () => import('../view/404')
	}]
})
export default router;

2. The interface obtains dynamic routing information (the data format is agreed with the backend at the same time). At this time, it only needs to return the routing table that the user has permission.

{
    
    	
	code:200
	message:'查询成功'
	success:true
	data: {
    
    
	    router: [
	      {
    
    
	        path: "/",
	        component: "index",
	        name: "home",
	        meta: {
    
    
	          title: "Home"
	        },
	        children: [
	          {
    
    
	            path: "menu1",
	            name: "menu1",
	            component: "menu1",
	            meta: {
    
    
	              title: "菜单1",
	              icon: "el-icon-info"
	            }
	          }
	        ]
	      }]
	 }
}

3. Here component is a string, which needs to be converted into a path, and then save the processed data in vuex and localStorage.

 function filterRouter(routers) {
    
     // 遍历后台传来的路由字符串,转换为组件对象
    const accessedRouters = routers.filter(route => {
    
    
      if (route.component) {
    
    
          route.component = _import(route.component)
      }
      if (route.children && route.children.length) {
    
    
          route.children = filterRouter(route.children)
      }
      return true
    })
    return accessedRouters
  }

function _import (file) {
    
    
    return () => import('../views/' + file)
}

4. In the created life cycle of the App.vue file, use the addRoutes method to add the latest routing table processed by the permission data to the router.

//处理好数据之后
this.$router.options.routes = routerList;
this.$router.addRoutes(routerList);

5. On the menu page, use this.$router.options.routers to get the latest routing object, and render the menu bar through the v-for loop.

Suggestion : When storing the processed routing table in localStorage, it is best to encrypt it to prevent users from modifying it locally.

Guess you like

Origin blog.csdn.net/weixin_43299180/article/details/114276852