动态添加/注册路由之addRoutes

addRoutes:动态添加/注册路由,一般多用于后台返回菜单树的管理系统。

解决管理系统权限时一般可采用路由守卫按权限限制是否允许访问某些路由,但当权限分类众多、或者是时而有某些路由时而又没有时,用路由守卫可能将写众多判断,更不利于后期维护,这时候的路由守卫看起来不再是那么合适了。

用addRoutes会有不一样的结果吗?动态添加路由将会从根源上切死访问权限,而不是去判断。设想一下,假如一个路由都不存在,那你去访问它,还需要去做大量判断他是否有权限吗?

当然如果不是后台返回菜单树,那两种解决方案可能看起来差别并不是很大,因需要前端去判断是否去注册该路由,这种方式与添加路由守卫去判断时候允许访问该路由的代码逻辑量区别不大

总体来说如果是后台返回菜单树,建议使用addRoutes,如果不返回菜单树则根据权限是否简单明了去区分,如果简单明了则使用路由守卫,否则建议采用addRoutes(路由守卫也并不是不行)

addRoutes用法实例(下例是在app.vue中使用,具体看实际需求):

import { mapActions } from 'vuex'
export default {
  name: 'App',
  data(){
  	return{
  	}
  },
  created(){
  	//使用定时器模拟请求后台获取菜单树
  	setTimeout(()=>{
  		//获取菜单树success,假设返回实例如下
  		var menuTree = [
  			{
  				name:'首页',//路由名称
  				disabled:false,//是否具有访问权限,true代表被禁用
  			},
  			{
  				name:'订单',
  				disabled:false,
  				children:[
  					{
		  				name:'历史订单',
		  				disabled:true,
		  			},
		  			{
		  				name:'进行中订单',
		  				disabled:false,
		  			},
		  			{
		  				name:'订单详情',
		  				disabled:false,
		  			},
  				]
  			},
  			{
  				name:'我的',
  				disabled:true,
  				children:[
  					{
		  				name:'我的钱包',
		  				disabled:true,
		  			},
		  			{
		  				name:'我的信息',
		  				disabled:true,
		  			},
  				]
  			},
  		];
  		//根据返回菜单树与前端拟定菜单树逻辑处理(匹配vue组件),获取出实际菜单树
  		//前端拟定菜单树假设如下
  		var draftTree = [
  			{
  				name:'首页',//路由名称
  				path:'index',//路由
  				component:()=>import("@/pages/index")//对应的vue组件
  			},
  			{
  				name:'订单',
  				path:'order',
  				component:()=>import("@/pages/order"),
  				children:[
  					{
		  				name:'历史订单',
		  				path:'orderHistory',
		  				component:()=>import("@/pages/order/history"),
		  			},
		  			{
		  				name:'进行中订单',
		  				path:'orderNew',
		  				component:()=>import("@/pages/order/new"),
		  			},
		  			{
		  				name:'订单详情',
		  				path:'orderDetails',
		  				component:()=>import("@/pages/order/details"),
		  			},
  				]
  			},
  			{
  				name:'我的',
  				path:'a',
  				component:()=>import("@/pages/a"),
  				children:[
  					{
		  				name:'我的钱包',
		  				path:'ab',
		  				component:()=>import("@/pages/a/ab"),
		  			},
		  			{
		  				name:'我的信息',
		  				path:'ac',
		  				component:()=>import("@/pages/a/ac"),
		  			},
  				]
  			},
  		];
  		//逻辑处理此处省略(遍历menuTree,匹配插入所需字段),处理结果如下
  		var menuArr = [
  			{
  				name:'首页',//路由名称
  				disabled:false,//是否具有访问权限,true代表被禁用
  				path:'index',//路由
  				component:()=>import("@/pages/index")//对应的vue组件
  			},
  			{
  				name:'订单',
  				disabled:false,
  				path:'order',
  				component:()=>import("@/pages/order"),
  				children:[
  					{
		  				name:'历史订单',
  						disabled:true,
		  			},
		  			{
		  				name:'进行中订单',
  						disabled:false,
		  				path:'orderNew',
		  				component:()=>import("@/pages/order/new"),
		  			},
		  			{
		  				name:'订单详情',
  						disabled:false,
		  				path:'orderDetails',
		  				component:()=>import("@/pages/order/details"),
		  			},
  				]
  			},
  			{
  				name:'我的',
  				disabled:true,
  				children:[
  					{
		  				name:'我的钱包',
  						disabled:true,
		  			},
		  			{
		  				name:'我的信息',
  						disabled:true,
		  			},
  				]
  			},
  		];
  		//将菜单添加至vuex,供菜单组件展示使用
  		this.setMenus(menuArr);
  		//遍历匹配生成后的菜单树(此树两层,如果是四层以及以上可以考虑递归),生成router树
  		var routeTree = [];
  		for(var i = 0 ; i < menuArr.length ; i++){
  			if(!menuArr[i].disabled){
  				if(menuArr[i].children){
  					var children = [];
  					for(var j = 0 ; j < menuArr[i].children.length ; j++){
  						if(!menuArr[i].children[j].disabled){
	  						children.push({
								path: menuArr[i].children[j].path,
				      				name: menuArr[i].children[j].path,
				          			component: menuArr[i].children[j].component,
	  						})
  						}
  					}
  					if(children.length){
						children.push({
							path: '/',
							redirect: children[0].path
						})
				  		children.push({
							path: '*',
							redirect: children[0].path
						})
  					}
  					routeTree.push({
		  				path: '/' + menuArr[i].path,
		          			component: menuArr[i].component,
		          			children
		  			})
  				}else{
					routeTree.push({
		  				path: '/' + menuArr[i].path,
		      				name: '/' + menuArr[i].path,
		          			component: menuArr[i].component,
		  			})
  				}
  			}
  		}
  		if(routeTree.length){
  			routeTree.push({
		    		path: '/',
				redirect: routeTree[0].path
  			})
  			routeTree.push({
		    		path: '*',
				redirect: routeTree[0].path
  			})
  		}else{
	  		routeTree.push({
		    		path: '/fail',
		    		name: 'fail',
		    		component: ()=>import("@/components/fail")
			})
			routeTree.push({
		    		path: '/',
				redirect: '/fail'
  			})
  			routeTree.push({
		    		path: '*',
				redirect: '/fail'
  			})
  		}
		//注册路由
  		this.$router.addRoutes(routes)
		//路由注册完成后跳转
		if(routeTree.length){
			this.$router.push({
				path: routeTree[0].path
			})
		}else{
			this.$router.push({
				path: '/fail'
			})
		}
  	},1000)
  },
  methods:{
  	...mapActions({
		setMenus: 'setMenus'
	}),
  }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风舞红枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值