element动态路由的配置

基于vue+element,把静态路由改为动态路由

修改动态路由的过程
第一步:修改理由配置文件,只留下login, router/index.js

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router);

const commonRoutes = [
	{
		path: '/login',
		type: 'login',
		component: () => import('@/views/login'),
	}
];

const createRouter = () => new Router({
	linkActiveClass: 'active',
	routes: commonRoutes
});

const router = createRouter()

export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher 
}

export default router


第二步:加工后台返回的json,成路由,utils/index.js

import {resetRouter } from '../router'
/**
  * 合并远程路由到本地路由
  * @param: subList [Array] 远程路由列表
  * @param: routes [Array] 本地路由列表
  * */
 export function mergeRoutes(subs) {
	
	//console.log(subs);
	
	let str1,str2,str3,str4 = [];
	
	if(subs){
		
					
		for (let i = 0; i < subs.length; i++) {
			str3 = [];
			
			//如果还有下一层先进去
			if(subs[i].children && subs[i].children.length > 0){
				let list1 = subs[i].children;
				
				for(let x = 0; x < list1.length; x++){
					str2 = [];
					if(list1[x].external == "1" ){//说明是外部链接,需要自己拼装
						
						//如果path=/blank,说明是空白页,需要另外处理
						if(list1[x].path == '/blank'){
							
							let temp = {
										path : list1[x].path,
										name : list1[x].name,
										menuShow : list1[x].menuShow == '1'? true: false,
										component: () => import(`@/views/nav/leftNav`),
										iconCls: list1[x].iconCls,
										meta: {
											apiActiveMenu : list1[x].meta
										},
										leaf: list1[x].leaf == '1'? true: false,
										children: [
											{
												path : list1[x].path,
												name : list1[x].name,
												menuShow : list1[x].menuShow == '1'? true: false,
												component: () => import(`@/views${list1[x].component}`),
										
											}
										],
									}; 
									
							str3.push(temp);
						}else{
							let temp = {
										path : list1[x].path,
										name : list1[x].name,
										menuShow : list1[x].menuShow == '1'? true: false,
										component: () => import(`@/views/nav/leftNav`),
										iconCls: list1[x].iconCls,
										meta: {
											apiActiveMenu : list1[x].meta
										},
										leaf: list1[x].leaf == '1'? true: false,
										external: list1[x].external == '1'? true: false,
										children: [
											{
												path : list1[x].path,
												name : list1[x].name,
												menuShow : list1[x].menuShow == '1'? true: false,
												component: () => import(`@/views/nav/rightC`),
										
											}
										],
									}; 
									
							str3.push(temp);
						}
						
						//跳出本次循环
						continue;
					}
					else if(list1[x].children && list1[x].children.length > 0){
						let list2 = list1[x].children;
						
						for(let y = 0; y< list2.length; y++){
							str1 = [];
							
							if(list2[y].children && list2[y].children.length >0){
								let list3 = list2[y].children;
								
								for(let z = 0 ; z < list3.length; z++){
									
									let temp = {
										path : list3[z].path,
										name : list3[z].name,
										menuShow : list3[z].menuShow == '1'? true: false, 
										component: () => import(`@/views${list3[z].component}`),
										meta: {
											apiActiveMenu : list3[z].meta
										},
										leaf: list3[z].leaf == '1'? true: false,
									};
									
									str1.push(temp);
									
								}
																
							}
							
							let temp = {
										path : list2[y].path,
										name : list2[y].name,
										menuShow : list2[y].menuShow == '1'? true: false,
										component: () => import(`@/views${list2[y].component}`),
										children: str1,
										meta: {
											apiActiveMenu : list2[y].meta
										},
										leaf: list2[y].leaf == '1'? true: false,
									}; 
									
							str2.push(temp);
							
						}
												
					}
					
					//不要问我为什么前端这么玩,后端不改,只有前端改,以后会是个天坑					
					if(str2.length>0){//如果上一层leaf是true,这一层的第一个想办法排序为true
						if(!str2[0].menuShow){
							var obj={} ;
							for(var r = 0 ; r< str2.length ;r++){
								if(str2[r].menuShow){//和第一个换位
									obj = str2[r];
									str2[r] = str2[0];
									str2[0] = obj;
									break;
								}
							}	
							
						}
	
					}
					
					let temp = {
										path : list1[x].path,
										name : list1[x].name,
										menuShow : list1[x].menuShow == '1'? true: false,
										component: () => import(`@/views${list1[x].component}`),
										children: str2,
										iconCls: list1[x].iconCls,
										meta: {
											apiActiveMenu : list1[x].meta
										},
										leaf: list1[x].leaf == '1'? true: false,
									}; 
									
					str3.push(temp);
					
				}
				
			}
			
			//拼接的时候,有一个bug,就是在第一层subs中,定义的重定向redirect
			//指定的路径,如果在路由中不存在,需要重新定义值
			let redirect = subs[i].redirect;
			let tag = false;//如果路径在路由中存在true
			
			
			if(!tag){//说明需要设置默认的跳转路径redirect值
				
				if(subs[i].children[0].leaf == "0"){//说明是菜单,需要进入下一层
					if(subs[i].children[0].children[0].leaf == "0"){//说明是菜单,需要进入下一层
						var arr  = subs[i].children[0].children[0];
						
						if(arr.leaf == "0"){
							for(var e = 0 ; e<arr.children.length; e++){
								if(arr.children[e].menuShow == '1' && arr.children[e].leaf == '1'){
					//				console.log(arr.children[e]);
									redirect = arr.children[e].path;
									break;
								}
							}
						}else{
							redirect = arr.path;
						}
						
					}else{
						
						var arr = subs[i].children[0].children;
						for(var t = 0 ;t < arr.length ; t++){
							if(arr[t].menuShow == '1'){
								redirect = arr[t].path;
								break;
							}
						}
					}
				}else{
					redirect = subs[i].children[0].path;
				}
				

			}
			
			console.log(redirect);
			
			let temp = {
					path : subs[i].path,
					name : subs[i].name,
					menuShow : subs[i].menuShow == '1'? true: false,
					component: () => import(`@/views${subs[i].component}`),
					children: str3,
					iconCls: subs[i].iconCls,
					redirect: redirect,
					meta: {
						apiActiveMenu : subs[i].meta
					},
					leaf: subs[i].leaf == '1' ? true: false,
					
				};
				
			str4.push(temp);
				
		}
				
	}
  
  str4.push({
		path: '*',
		component: () => import('@/components/404.vue')
	});
	return str4;

 }


/**
 * routes   要添加的路由
 * 因为addRoutes()会重复添加路由,自定义的方法先去
 * 初始化再添加避免重复添加
 */
export function selfaddRoutes(routes) {
	router.matcher = new Router().matcher;
  router.addRoutes(routes);
}

export function resetTokenAndClearUser() {
  // 退出登陆 清除用户资料
  sessionStorage.clear();
  // 重设路由
  resetRouter()
}

第3步:路由的一些判断,解决了路由的重复添加的问题,api/premission.js

import router from '@/router/index'
import store from '@/store/index'
import { mergeRoutes, resetTokenAndClearUser } from '@/utils'

//防止重复添加动态路由
let hasMenus = false;
// 拦截登录,session验证
router.beforeEach((to, from, next) => {
    if(sessionStorage.getItem("token")){
      if(to.path === '/login'){

        next();
      }else{
        if(hasMenus){
          next();
        }else{
          try {
            const menus = JSON.parse(sessionStorage.getItem("menus"));
            const routes = mergeRoutes(menus);
            router.options.routes = router.options.routes.concat(routes);
			router.addRoutes(router.options.routes);
            hasMenus = true
            next({path: to.path})
        } catch (error) {
            resetTokenAndClearUser()
            next(`/login?redirect=${to.path}`)
        }
        }
      }
    }else{
      hasMenus = false
      sessionStorage.clear();
      if(to.path === '/login'){
        next();
      }else{
        next(`/login?redirect=${to.path}`)
      }
    }
})

router.onError((error) => {
  const pattern = /Loading chunk (\d)+ failed/g;
  const isChunkLoadFailed = error.message.match(pattern);
  const targetPath = router.history.pending.fullPath;
  if (isChunkLoadFailed) {
    router.replace(targetPath);
  }
});

第四步,把components/nav复制到views下
在这里插入图片描述

接下来,就是对于路由的配置。

这里需要注意的几个点,搞不清路由的配置就会出现问题。
在这里插入图片描述
类型中,有栏目、目录、菜单,先说清楚他们的区别
在这里插入图片描述
我们新增资源的时候,其实,就是区分是目录还是菜单。如果是最底层就是菜单,我会在路由配置中加入leaf:true。

第二点, 以商品招标为例,下面是静态的路由,我们动态路由应该怎么配置

{
      path: '/tendersManager',
      type: 'enterprise',
      name: 'tenders',
      redirect: '/tendersManager/tenderscenter',
      component: Home,
      menuShow: true,
      meta:{
        name:"商品招标"
      },
      children: [
        {
          path: '/tendersManager/tenderscenter',
          component: LeftNav,
          name: 'tenderscenter', // 当前路由的name
          leaf: true, // 只有一个节点
          iconCls: 'iconfont icon-home', // 图标样式class
          menuShow: true,
          children: [
            { path: '/tendersManager/tenderscenter', component: TenderCenter, name: '商品招标中心', menuShow: true }
          ]
        },
        {
          path: '/tendersManager/missionmanager',
          component: LeftNav,
          name: '商品招标管理',
          iconCls: 'el-icon-menu',
          menuShow: true,
          children: [
            { path: '/tendersManager/missionmanager', component: TenderMisssion, name: '招标任务管理', menuShow: true },
            
            { path: '/tendersManager/missionmanager/add', component: TenderAdd, name: '新建招标任务', menuShow: false,
              meta:{
                apiActiveMenu: '/tendersManager/missionmanager/add'
              }
            },

            { path: '/tendersManager/missionmanager/detail', component: TenderDetail, name: '查看', menuShow: false,
              meta:{
                apiActiveMenu: '/tendersManager/missionmanager/detail'
              }
            },
          ]
        },
      ]
    },

在这里插入图片描述
其中需要注意,招标任务管理中有俩个按钮
在这里插入图片描述
分别对应的俩个页面,这个时候需要去配置路由,我为了方便判断,需要把查询和新增的路由配置在【招标任务管理】同级下。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值