vue实现菜单权限控制

 

需求:

当前系统登录用户具有不同的角色,前端页面需要针对不同角色用户来展现不同的菜单,从而需要实现菜单权限控制功能。

思路:

  1. 获取后台返回的菜单数据;
  2. 根据菜单数据遍历加载需要的菜单路由,没有权限的菜单路由就不加载;
  3. 使用全局守卫导航配合实现。
  4. 特别说明:如果所有的菜单路由都加载,当用户在地址栏中输入路由路径就可以访问没有权限的菜单页面,这样就达不到菜单权限控制的需求;如果所有的菜单都加载并且使用全局守卫导航,在每次跳转路由的时候都去判断当前用户是否有这个权限,再决定是否跳转,这样虽然可行,但是考虑到前端性能的问题,还具有优化的空间。

具体步骤

  1. 新建2个路由文件,一个用于存放公共路由(router.js),一个用于引入所有的路由(components.js),如下
    router.js
    //通用页面路由
    const router = new Router({
      // mode:"history",
      routes: [
        {
          path: "/",
          redirect: "/login"
        },
        {
          path: "/login",
          name: "login",
          component: Login
        }
      ]
    })
    components.js
    const workplace = require("@/components/workplace/Workplace.vue").default;//工作台
    ......
    
    export default {
      workplace,
      ......
    }
  2. 获取后台返回的菜单数据,加载需要的路由,此步骤在全局守卫导航中实现
    router.js
    
    import api from "../api/api.js"
    import routeMap from "@/router/components.js"  //引入所有的组件
    var myRouter = [],   //存放具有权限的路由名称
    routerMeta = {},     //页面按钮权限控制相关,菜单权限可以不需要
    isFetchRemote = true;//保证菜单数据只加载一次
    
    //遍历树:将菜单数据转化成  
    function getMyRouter(datas) {
      for (var i in datas) {
        if (datas[i].isShow && datas[i].path != undefined && datas[i].path != "") {
          myRouter.push(datas[i].path);
          routerMeta[datas[i].path] = datas[i].meta
        }
        if (datas[i].child) {
          getMyRouter(datas[i].child);
        }
      }
    }
    // 全局守卫导航
    router.beforeEach((to, from, next) => {
      let username = sessionStorage.getItem('username');
      // 未登录状态;当路由到nextRoute指定页时,跳转至login
      if (!username) {
        next({ path: '/login' });
      } else if (isFetchRemote) {
        // 获取菜单权限数据
        api.get_menu_List({}).then(({ data }) => {
          if (data.code == 200) {
            isFetchRemote = false;
            let result = data.data;
            localStorage.setItem('workplaceMenu', JSON.stringify(result));
            getMyRouter(result);
            //根据具有权限的路由名称:myRouter ,按照路由配置的格式配置权限需要的路由
            let myRoutes = [];
            for (var i in myRouter) {
              myRoutes.push({
                name: myRouter[i],
                path: myRouter[i],
                meta: routerMeta[myRouter[i]],
                component: routeMap[myRouter[i]]
              })
            }
            let routeData = {
              path: "/index",
              name: "index",
              component: Index,
              redirect: '/index/workplace',
              children: myRoutes
            }
             //将动态配置好的路由:routeData添加到当前路由中,并添加404页面
            router.addRoutes([routeData].concat([
              { name: '404', path: '/404', component: Forbidden },
              { path: '*', redirect: '/404' }]));
            router.push({
              path: to.path,
              query: to.query
            });
          } else {
            isFetchRemote = false; true
          }
          next();
        })
      } else {
        next();
      }

    菜单格式

    [
            {
                id: "menu_0",
                name: "工作台",
                icon: "fa fa-dashboard",
                path: "",
                state_default: true,
                isShow: true,
                child: [
                    {
                        id: "menu_0_1",
                        name: "首页",
                        icon: "fa fa-dashboard",
                        path: "workplace",
                        toolData: [],
                        state_default: true,
                        isShow: true,//用于设置是否具有权限
                    }
                ]
            },
            {
                id: "menu_5",
                name: "项目",
                path: "/jz",
                icon: "fa fa-product-hunt",
                path: "",
                isShow: true,
                child: [],
            },
    ......
    ]

     

你可能感兴趣的:(Vue,vue,javascript)