步骤

  1. 前端登录传递 uid → 后端 → 请求路由权限API
  2. 后端返回用户路由权限列表 → 给前端
  3. 前端把数据 → 转为树形结构
  4. 树形结构 → 转为 vue 路由结构
  5. 把请求到的动态路由 → 与本地静态路由合并
  6. 根据树形结构化数据 → 生成菜单组件

数组转树结构

function dataToTree(parents, children) {
  parents.forEach(p => {
    children.forEach((c, i) => {
      // 只要遍历的时候,找到了当前child的父亲
      if (c.pid === p.id) {
        // 就把找到的当前child从拷贝的 children 中除名
        let _c = JSON.parse(JSON.stringify(children));
        _c.splice(i, 1);
        // 然后当前 child 有可能还有自己的 children 所以递归,把自己当 parents,从剩下 children 中找儿子
        dataToTree([c], _c);

        // 如果当前 parent 有 children ,就把当前 child 添加到 children 中去
        if (p.children) {
          p.children.push(c);
        } else { // 否则 直接添加
          p.children = [c];
        }
      }
    });
  });
  return parents;
}

let parents = data.filter(item => item.pid === -1);
let children = data.filter(item => item.pid !== -1);
const tree = dataToTree(parents, children);
console.log(tree);

要转的数据示例

var data = [{
  "scode": "910001",
  "id": "910001",
  "pid": -1,
  "sname": "医药医疗",
  "fChgRatio": -0.13
}, {
  "scode": "910002",
  "id": "910002",
  "pid": "910001",
  "sname": "创新药",
  "fChgRatio": 0.44
},
...];

树结构转 vue 路由结构

function generateRouter(userRouters) {
	let newRouters = userRouters.map(r => {
  	let router = {
    	path: r.path,
      name: r.name,
      component: () => import(`@/views/${r.name}`),
    };

    if (r.children) {
    	router.children = generateRouter(r.children);
    }

    return router;
  });

  return newRouters;
}

路由守卫

main.js

router.beforeEach((to, from, next) => {
	if (!store.state.hasAuth) {
  	await store.dispatch('setUserRouters');
    const newRoutes = generateRouter(store.state.userRouters);
    router.addRoutes(newRoutes);
    next({ path: to.path });
  } else {
  	next();
  }
});

递归组件

Untitled

按钮级别鉴权

  1. 和路由权限类似,返回按钮权限数据(一个数组,包含当前用户各种权限) 然后vuex本地缓存