vue根据角色动态路由的实现方式

45 篇文章 0 订阅
21 篇文章 1 订阅

思路:本地写死路由,根据登录角色添加不同的动态路由

  • 路由文件:分为静态路由和动态路由
  • 登录成功,判断角色,addRoute添加动态路由,并且存储路由数组
  • 根据路由数组生成菜单栏

方法一:

  • 直接获取路由this.$router.options.routes,但是addRoute添加的动态路由使用该方法获取不到,options里边没有
  • 解决方法:在addRoute添加动态路由前,手动拼接静态和动态路由,赋值给options。this.$router.options.routes = [全路由数组],但是页面手动刷新的时候还是会丢失动态添加的路由

方法二:

  • 在addRoutes添加动态路由前,将拼接路由存入vuex中,然后使用vuex中的路由生成菜单栏;
  • 但是刷新的时候vuex会丢失路由,可以吧vuex存本地,每次刷新重新在vuex中获取路由

bug:

  1. 本次采用的方法二
  2. 动态添加的路由,刷新后点击跳转404页面,{path:’*’,redirect: ‘/404’…}不能放在静态路由里,否则刷新的时候即便获取到了异步路由数据也会直接跳转到404,解决方法应该将该路由放在动态路由里
  3. 采用方法二,登录后addRoutes异步添加的路由可以正常跳转。但是浏览器刷新之后会路由会丢失,页面跳转不过去,在router.beforeEach()方法中发现刷新时to.name为null。解决方法:在路由守卫里判断如果to.name==null,重新添加一遍路由
  4. 使用addRoutes报错Error: [vue-router] “path“ is required in a route configuration.因为这个api已经废弃,新的api是addRoute(参数为对象,而不是数组),所以需要循环添加
    4.在路由守卫里判断如果to.name==null,重新添加一遍路由,之后next()。 vue-router报错Error: Navigation cancelled from “/course“ to “/user“ with a new navigation. 原因全局导航守卫中出现了页面跳转到了一个页面之后又重定向到了另一个界面,
    修改 next({ …to, replace: true })

router.js

import Vue from "vue";
import VueRouter from "vue-router";
import Layout from "@/layout/index";
import store from "../store/index";
Vue.use(VueRouter);

export const constantRoutes = [
  {
    path: "/",
    redirect: "/home",
    component: Layout,
    meta: {
      title: "首页",
      icon: "el-icon-s-home",
      path: "/home",
    },
    children: [
      {
        path: "home",
        name: "home",
        component: () => import("../views/Home"),
      },
    ],
  },
  {
    path: "/device",
    redirect: "/device/list",
    component: Layout,
    meta: {
      title: "设备管理",
      icon: "el-icon-mobile",
    },
    children: [
      {
        path: "list",
        name: "diviceList",
        component: () => import("../views/device/list"),
        meta: {
          title: "网关列表",
          path: "/device/list",
        },
      },
      {
        path: "log",
        name: "diviceLog",
        component: () => import("../views/device/log"),
        meta: {
          title: "监控日志",
          path: "/device/log",
        },
      },
      {
        path: "warn",
        name: "diviceWarn",
        component: () => import("../views/device/warn"),
        meta: {
          title: "预警设置",
          path: "/device/warn",
        },
      },
    ],
  },
  {
    path: "/login",
    component: () => import("../views/login/login"),
    hidden: true,
  },
  {
    path: "/404",
    component: () => import("../views/404"),
    hidden: true,
  },
];
// 在登陆成功时,获取用户身份,动态添加路由
// this.$router.addRoute(asyncRoutes)
export const asyncRoutes = [
  {
    path: "/user",
    component: Layout,
    meta: {
      title: "用户管理",
      icon: "el-icon-setting",
      path: "/user/list",
    },
    children: [
      {
        path: "list",
        name: "userList",
        component: () => import("../views/user/list"),
      },
    ],
  },
  {
    path: "*",
    redirect: "/404",
    hidden: true,
  },
];
const router = new VueRouter({
  routes: constantRoutes,
});

router.beforeEach((to, from, next) => {
  if (to.path == "/login") return next();
  const token = localStorage.getItem("token");
  if (!token) return next("/login");
  // 解决页面刷新,动态路由丢失,所以重新add
  if (!to.name && store.state.userInfo.role == 0) {
    asyncRoutes.forEach((item) => {
      router.addRoute(item);
    });
    next({ ...to, replace: true });
  } else {
    next();
  }
});
export default router;


vuex

import Vue from "vue";
import Vuex from "vuex";
import { constantRoutes, asyncRoutes } from "../router/index";
import router from "../router/index";
Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    open: true, //菜单栏是否展开
    userInfo: JSON.parse(localStorage.getItem("userInfo") || "{}"),
    routes: localStorage.getItem("routes")
      ? JSON.parse(localStorage.getItem("routes"))
      : constantRoutes,
  },
  mutations: {
    // 菜单的关闭
    changeOpen(state, data) {
      state.open = data;
    },
    // 存储用户信息
    // "userId":"afsdkasdfadsfds",
    //  "token":"xxxxxxxxxxxxxxxxxxxxxxx",
    //  "role":"1"   0:超级管理员 1:管理员
    saveUserInfo(state, data) {
      state.userInfo = data;
      localStorage.setItem("token", data.token);
      localStorage.setItem("userInfo", JSON.stringify(data));
    },
    // 动态路由,根据这个路由生成菜单
    saveRoutes(state) {
      if (state.userInfo.role == 0) {
        console.log(asyncRoutes);
        asyncRoutes.forEach((item) => {
          router.addRoute(item);
        });
        state.routes = constantRoutes.concat(asyncRoutes);
      } else {
        state.routes = constantRoutes;
      }
      localStorage.setItem("routes", JSON.stringify(state.routes));
    },
  },
  actions: {},
  modules: {},
});

login

			this.$axios
            .post("/supportOldMan/sysUser/loginCheck", {
              userName: this.ruleForm.name,
              passWord: this.ruleForm.pass,
            })
            .then((data) => {
              this.$store.commit("saveUserInfo", data);
              // 根据userInfo的身份信息保存路由路由
              this.$store.commit("saveRoutes");
              this.$message.success("登录成功");
              setTimeout(() => {
                this.$router.replace("/home");
              }, 1000);
            });
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Vue动态路由角色权限可以通过以下步骤实现: 1. 在路由配置文件中添加动态路由动态路由是指在运行时根据用户权限动态加载的路由。可以通过以下方式实现: ```javascript const routes = [ { path: '/', name: 'Home', component: Home, meta: { requiresAuth: true, role: ['admin', 'user'] } }, { path: '/admin', name: 'Admin', component: Admin, meta: { requiresAuth: true, role: ['admin'] } }, { path: '/user', name: 'User', component: User, meta: { requiresAuth: true, role: ['user'] } }, { path: '/login', name: 'Login', component: Login }, { path: '/404', name: 'NotFound', component: NotFound }, { path: '*', redirect: '/404' } ]; ``` 其中,meta属性用于保存路由元信息,requiresAuth表示该路由需要登录才能访问,role表示该路由需要的用户角色。 2. 在路由守卫中进行角色权限验证。路由守卫是指在路由跳转时进行拦截和验证的函数。可以通过以下方式实现: ```javascript router.beforeEach((to, from, next) => { const isLoggedIn = AuthService.isLoggedIn(); if (to.meta.requiresAuth && !isLoggedIn) { next('/login'); } else if (to.meta.role && to.meta.role.length > 0) { const userRole = AuthService.getUserRole(); if (to.meta.role.indexOf(userRole) === -1) { next('/404'); } else { next(); } } else { next(); } }); ``` 其中,AuthService是一个用于保存和获取用户登录和角色信息的服务。当路由需要登录才能访问时,如果用户未登录,则跳转到登录页面;当路由需要特定的用户角色时,如果用户角色不符合要求,则跳转到404页面;否则,继续进行路由跳转。 3. 在登录成功后保存用户登录和角色信息。可以通过以下方式实现: ```javascript const AuthService = { isLoggedIn() { return localStorage.getItem('isLoggedIn') === 'true'; }, setLoggedIn(value) { localStorage.setItem('isLoggedIn', value); }, getUserRole() { return localStorage.getItem('userRole'); }, setUserRole(role) { localStorage.setItem('userRole', role); } }; ``` 其中,setLoggedIn和setUserRole用于保存登录状态和用户角色信息,isLoggedIn和getUserRole用于获取登录状态和用户角色信息。 通过以上三个步骤,就可以实现Vue动态路由角色权限。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小曲曲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值