vue中权限控制实现1:后端控制

357 阅读2分钟

1.前端定义的动态路由,后面由后端返回 image.png

2.前端的静态路由

import Vue from "vue";
import VueRouter from "vue-router";
import { BASE_PATH } from "@/config";

Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "Layout",
    component: () => import("@/layout/index"),
    redirect: "/home",
    children: [],
  },
  {
    path: "/login",
    name: "login",
    meta: {
      title: "登录",
    },
    component: () => import("@/views/login"),
  },
  // {path: '*', redirect: '/404'},
  {
    path: "/404",
    meta: {
      title: "页面丢失",
    },
    component: () => import("@/views/404"),
  },
];

const router = new VueRouter({
  routes,
  base: BASE_PATH,
});

let originPush = VueRouter.prototype.push;

VueRouter.prototype.push = function (location) {
  return originPush.call(this, location).catch((e) => e);
};

let originReplace = VueRouter.prototype.replace;
VueRouter.prototype.replace = function (location) {
  return originReplace.call(this, location).catch((e) => e);
};

export default router;
  1. 按需导入动态路由文件 ,然后定义一个定时器封装一个异步抛出动态路由数据,后面定时器就是接口,返回的也就是后台给的动态路由信息
import { routes } from "@/router/routes";
export const getUserMenuList = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(routes);
    }, 500);
  });
};

4.定义白名单,不需要权限的页面, 在这个路由js文件发送请求获取数据保存在vuex中, vuex会有个缺点,页面刷新数据丢失,所以在vuex中需要去本地存储,并且页面刷新的时候,如果菜单列表是空,就再次发送请求获取

import router from "@/router/index";
import store from "@/store";
import { getUserMenuList } from "@/api/user";

let menuList = null; // 菜单列表
let whiteList = ["/login", "/404"]; //白名单

router.beforeEach(async (to, from, next) => {
  let isLogin = store.getters.userInfo; // 是否登录
  // 白名单 不需要鉴权的页面
  if (whiteList.includes(to.path)) return next();
  //未登录
  if (!isLogin) return next("/login");
  //刷新操作
  if (!menuList) {
    menuList = await getUserMenuList();
    store.dispatch("setMenuList", menuList);
    menuList.forEach((v) => {
      router.addRoute("Layout", v);
    });
    router.addRoute({
      path: "*",
      redirect: "/404",
    });
    next({ ...to });
  } else {
    return next();
  }
});
  1. 接口返回的数据处理, type == 10就是说是不显示的路由
export const getUserMenuList = () => {
  return server({
    url: "/energy-efficiency-server/sysMenu/getUserMenus",
    method: "get",
  }).then((res) => {
    let originList = res.data;
    function diMenu(list) {
      list.sort((a, b) => a.sort - b.sort);
      return list.map((item) => {
        return {
          path: item.router,
          name: item.router,
          component: () => import(`@/views${item.componentPath}`),
          children:
            item.children && item.children.length
              ? diMenu(item.children)
              : null,
          meta: {
            title: item.name,
            hidden: item.type == 10,
          },
        };
      });
    }
    return diMenu(originList);
  });
};

6 添加一个递归函数,用来处理后台返回的动态路由列表(包括左侧菜单栏 和一些路由跳转的,但是路由跳转不需要显示在侧边栏,那么就需要对后台返回的数据进行处理),这里需要用到filter map加上递归(不显示的在路由meta:{hidden:true}配置)

const getData = (routes)=>{
   return v.filter((item)=>{
     return  !item.meta.hidden
   }).map((item)=>{ if(item.children){
      item.children = getData(item.children)
     }
      return item 
     })
   }