导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

软实力

算法

UI、组件库

Node

业务技能

针对性攻坚

AI


步骤

  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 本地缓存
  2. hasBtnPermission 全局指令,在 inserted 钩子中判断有没有权限(指令数组中找有没有指令传入的 add 权限)
    1. 有,disable 为 false
    2. 无,disable 为 true
<button v-permission="'add'">添加</button>
import permission from './directives/permission'
directives: { permission }
inserted(el, bindings, vnode) {
  let btnPermissionValue = bindings.value;
  let boolean = vnode.context.$store.state.buttomPermission[btnPermissionValue];
  !boolean && el.disabled = true;
}

https://www.zhuxianfei.com/jishu/js/56196.html

或者根据角色分:

<template>
  <!-- Admin can see this -->
  <el-tag v-permission="['admin']">admin</el-tag>

  <!-- Editor can see this -->
  <el-tag v-permission="['editor']">editor</el-tag>

  <!-- Both admin or editor can see this -->
  <el-tag v-permission="['admin','editor']">Both admin or editor can see this</el-tag>
</template>

<script>
// Of course you can also register it for the sake of convenience.
import permission from '@/directive/permission/index.js'
export default{
  directives: { permission }
}
</script>
import store from '@/store'

function checkPermission(el, binding) {
  const { value } = binding
  const roles = store.getters && store.getters.roles

  if (value && value instanceof Array) {
    if (value.length > 0) {
      const permissionRoles = value

      const hasPermission = roles.some(role => {
        return permissionRoles.includes(role)
      })

      if (!hasPermission) {
        el.parentNode && el.parentNode.removeChild(el)
      }
    }
  } else {
    throw new Error(`need roles! Like v-permission="['admin','editor']"`)
  }
}

export default {
  inserted(el, binding) {
    checkPermission(el, binding)
  },
  update(el, binding) {
    checkPermission(el, binding)
  }
}