Vue 动态路由的实现(后台传递路由,前端拿到并生成侧边栏)

前言

后台传来当前用户对应权限的路由表(扁平数据),前端通过调接口拿到后处理(后端处理路由)

代码

后端扁平数据

[
  {id:1, pId:0, name:'example1', label:'菜单一', path:'/example1', component:'Main', icon:null},
  {id:2, pId:0, name:'example2', label:'菜单2', path:'/example2', component:'Main', icon:null},
  {id:3, pId:1, name:'table', label:'表格', path:'table', component:'/basic/table/index', icon:null},
  {id:4, pId:2, name:'tree', label:'树形菜单', path:'tree', component:'/basic/tree/index', icon:null}
]

路由

[
	{
	  name: 'example1',
	  path: '/example1',
	  component: Main,
	  meta: {
	    name : '菜单一'
	  },
	  children: [
	    {
	      name: 'table',
	      path: '/table',
	      component: () => import('_v//basic/table/index.vue'),
	      meta: {
	        name : '表格'
	      }
	    }
	  ]
	},
	 {
	   name: 'example2',
	   path: '/example2',
	   component: Main,
	   meta: {
	     name : '菜单2'
	   },
	   children: [
	     {
	       name: 'tree',
	       path: 'tree',
	       component: () => import('_v/basic/tree/index.vue'),
	       meta: {
	         name : '树形菜单'
	       }
	     }
	   ]
	 }
]

扁平数据转路由

const createRouter = () => new VueRouter({
     
  mode: 'hash',
  routes: constantRoutes
})


const router = createRouter();



// 添加动态路由
export const addAsyncRoutes = function(routes) {
     
  // 添加其他项目路由前,重置 matcher
  const newRouter = createRouter();
  router.matcher = newRouter.matcher; // the relevant part
  
  router.options.routes.push(...routes)
  router.addRoutes(routes);
}

// 把后台传过来的字符串型的component转化为真正的组件
const _import = function(file) {
     
  return () => import('_v' + file + '.vue')
}

//遍历后台传来的路由字符串,转换为组件对象
const filterAsyncRouter = (menuList) => {
     
  let list = JSON.parse(JSON.stringify(menuList));

  const nodeMap = new Map();
  const result = [];
  var meta;
  for(const node of list) {
     
    meta = {
     
      name: node.label,
      icon: node.icon
    }
    if(node.component === 'Main'){
     
      node.component = Main;
    } else {
     
      node.component = _import(node.component);
    }
    node.meta = meta;
    nodeMap.set(node.id, node);
  }
  for(const node of list) {
     
    const parent = nodeMap.get(node.pId);
    (parent ? (parent.children ? parent.children : parent.children = []) : result).push(node);
  }
  return result;
}

login.vue

addAsyncRoutes();

参考:
Vue 动态路由的实现(后台传递路由,前端拿到并生成侧边栏)

你可能感兴趣的:(前端)