Vue路由权限控制的终极解决方案

46 阅读1分钟

cover.jpg

没有权限的路由不显示,通过给 el-sub-menu 加 vAdmin 实现

const vAdmin = {

  mounted(el) {
    if (store.state.userInfo.role !== 1) {
      el.parentNode.removeChild(el);
    }
  },
};

!!!  但通过路径仍能走到实际的组件

动态路由中要进行 auth 判断以让非管理员 routes 里无要权路由

const getDynamicRoutes = () => {
  dynamicRoutes.forEach((route) => {
    authCheck(route) && router.addRoute("backstage", route);
  });
  store.commit("setDynamicStatus", true);
};
const authCheck = (route) => {
  if (!route.auth) {
    return true;
  } else {
    return store.state.userInfo.role === 1;
  }
};

!!!  但编辑登录后管理员再登录,会发现用户管理是 404
发现是因为第一次编辑登录后 getDynamicRoutes 里

store.commit("setDynamicStatus", true);

而退出后因为 store.state.dynamicStatus 为 true 而不进行路由的重新获取

每次登录时将 store.state.dynamicStatus 置为 false,只要登录就重新获取动态路由

//Login.vue
if (res.data.ActionType === "ok") {
  store.commit("setDynamicStatus", false);
  store.commit("setUserInfo", res.data.data);
  router.push("/home");
}

!!!  但多次登录时,调用 router.getRoutes(),发现每登录一次 routes 的 length 就会加 1,多一个重复的

{path: '/', redirect: '/home'}

说明 router 在 push 到'login'前/后没有重置

每次进入登录页面就重置 router

法一

//从别的路径到/login就刷新页面
 {
    path: "/login",
    name: "login",
    beforeEnter: (to, from) => {
      if (from.path !== "/login" && from.path!=='/') {
        location.reload()
        //location.reload会刷新页面重置vue实例和router
        return true;
      } else {
        return true;
      }
    },
    component: () => import("@/views/Login.vue"),
  }

法二:法一稍有不慎容易造成无限刷新且有刷新的视觉效果 ,于是设计了更稳妥的法二

//在进入login前删掉动态添加路由的父路由
if (to.path == "/login") {
  localStorage.removeItem("token");
  store.commit("setUserInfo");
  router.removeRoute("backstage");
  return true;
}
//登录后在动态添加路由前把父路由加进去
if (!router.hasRoute("backstage")) {
  router.addRoute("backstage", {
    path: "/backstage",
    name: "backstage",
    component: () => import("@/views/BackStage.vue"),
  });
}
dynamicRoutes.forEach((route) => {
  authCheck(route) && router.addRoute("backstage", route);
});

OK 了家人了,找不出 BUG 了