vue-element-admin 动态加载路由菜单,实现管理菜单权限控制

3 篇文章 0 订阅

vue-element-admin 动态加载后端返回菜单,实现后台管理菜单权限控制

PS

首次使用vue-element-admin开发一个后台管理系统,细读官方教学

手摸手,带你用 vue 撸后台 系列二(登陆权限篇)

给的示例是前端实现权限控制,无法满足也无需求,于是乎,就查阅各种资料,查看示例,整理出如下方法,实现前端通过后端的接口菜单,实现动态加载后台菜单。
如有想实现的小白,可按照我如下步骤,比对,进行实现。
唯一需要注意的是,后台返回的json数据结构更改

主要改变文件

  1. /src/router/index.js 修改变量:asyncRoutes 为如下:

    export const asyncRoutes = [
    	{
    		path: '*',
    		redirect: '/404',
    		hidden: true
    	}
    ]
    
  2. src\store\modules\permission.js 做如下修改:

    import { asyncRoutes, constantRoutes } from '@/router'
    import { getAuthMenu } from '@/api/menu'
    import Layout from '@/layout'
    
    /**
    * Use meta.role to determine if the current user has permission
    * 使用 meta.role 确定当前用户是否具有权限
    * @param roles
    * @param route
    */
    function hasPermission(roles, route) {
    	if (route.meta && route.meta.roles) {
     		return roles.some(role => route.meta.roles.includes(role))
    	} else {
     		return true
    	}
    }
    
    /**
    * 后台查询的菜单数据拼接成路由格式的数据
    * @param routes
    * @param data
    * @param is_children
    */
    export function generaMenu(routes, data, is_children = false) {
    	data.forEach(item => {
     	const menu = {
       		path: item.path,
       		component: item.component === '#' ? Layout : resolve => require([`@/views${item.component}`], resolve),
       		name: item.name,
       		meta: item.meta
     	}
     	if (is_children === false) {
       		menu.children = []
       		menu.alwaysShow = item.alwaysShow
       		menu.redirect = item.redirect
     	}
     	if (item.children && is_children === false) {
       		generaMenu(menu.children, item.children, true)
     	}
     	console.log(menu)
     	routes.push(menu)
    	})
    }
    
    /**
    * Filter asynchronous routing tables by recursion
    * 通过递归过滤异步路由表
    * @param routes asyncRoutes
    * @param roles
    */
    export function filterAsyncRoutes(routes, roles) {
    	const res = []
    	routes.forEach(route => {
     		const tmp = { ...route }
     		if (hasPermission(roles, tmp)) {
       			if (tmp.children) {
         			tmp.children = filterAsyncRoutes(tmp.children, roles)
       			}
       			res.push(tmp)
     		}
    	})
    	return res
    }
    const state = {
    	routes: [],
    	addRoutes: []
    }
    
    const mutations = {
    	SET_ROUTES: (state, routes) => {
     		state.addRoutes = routes
     		state.routes = constantRoutes.concat(routes)
    	}
    }
    
    const actions = {
    	generateRoutes({ commit }, roles) {
     		return new Promise(resolve => {
       		const loadMenuData = []
       		// 先查询后台返回左侧菜单数据并将数据添加到路由
       		getAuthMenu().then(response => {
         		let data = response
         		if (!response.result) {
           			alert(JSON.stringify(response.message))
         		} else {
           			data = response.data
           			Object.assign(loadMenuData, data)
           			const tempAsyncRoutes = Object.assign([], asyncRoutes)
           			generaMenu(tempAsyncRoutes, loadMenuData)
           			let accessedRoutes
           			if (roles.includes('admin')) {
             			accessedRoutes = tempAsyncRoutes || []
           			} else {
             			accessedRoutes = filterAsyncRoutes(tempAsyncRoutes, roles)
           			}
           			commit('SET_ROUTES', accessedRoutes)
           			resolve(accessedRoutes)
         		}
       		}).catch(error => {
         		console.log(error)
       		})
     	})
    }
    }
    
    export default {
    	namespaced: true,
    	state,
    	mutations,
    	actions
    }
    
  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值