vue后台管理系统,动态权限路由怎么写。

15 篇文章 0 订阅
2 篇文章 0 订阅

做后台管理系统,我们经常需要对各个用户进行权限的管理,不同权限的用户所能看到的页面也不相同,那么我们应该怎么做呢。下面,我说说我近期的实战案例。

一、编写路由

写路由这一步正常写就行,没什么特别的地方

{
    path: "/",
    redirect: "/login",
    children: []
  },
  {
    path: "/login",
    component: Login,
    name: "",
    meta: {
    },
    children: []
  },
  {
    path: "/index",
    name: "index",
    component: Layout,
    componentname: "home",
    meta: {
      requireAuth: true
    },
    redirect: "/index/test1",
    children: [
      {
        path: "/index/test1",
        name:"test1",
        componentname: "test1",
        component: Test1,
        children: []
      },
      {
        path: "/index/test2",
        name:"test2",
        componentname: "test2",
        component: Test2,
        children: []
      }
    ]
  },
  {
    path: "/box",
    name: "box",
    component: Layout,
    componentname: "home",
    redirect: "/box/test1",
    children: [
      {
        path: "/box/test1",
        name: "box1",
        componentname: "box1",
        component: Box1,
        children: []
      },
      {
        path: "/box/test2",
        name:"box2",
        componentname: "box2",
        component: Box2,
        children: []
      }
    ]
  },

路由怎么写就不过多赘述了,相信会看这篇文章的,路由也都会写。

二、将路由信息交由后台进行保存配置

这也很简单,将你配好的各种路由对应哪个页面的信息发给后端就行,后端需要进行配置,用于在不同权限的人登录时返回你不同的有权限的路由信息。
返回信息有多种,可以使name,也可以是数字,这个没有固定的,自认为自己怎么好弄怎么来,我一般直接让后端直接返给我有权限的路径数组。

三、在vuex中写动态添加路由的方法

import { defaultRouter, addRouter } from "@/router/index";
import lodash from "lodash";
const routerData = {
  state: {
    routers: [],
    addRouters: []
  },
  mutations: {
    setRouters: (state, routers) => {
      state.addRouters = routers; // 保存动态路由用来addRouter
      state.routers = defaultRouter.concat(routers); // 所有有权限的路由表,用来生成菜单列表
    }
  },
  actions: {
    newRoutes({ commit }, options) {
      if (!options.menus) { //判断调用的时候参数中有没有路由信息
        commit("setRouters", []);
        return;
      }

      //  通过递归路由表,删除掉没有权限的路由
      function eachSelect(routers, componentname) {
        var newrouter = lodash.cloneDeep(routers);
        newrouter.forEach(item => {
          if (item && item.children && item.children.length) {
            eachSelect(
              routers[routers.findIndex(v => v.name === item.name)].children,
              componentname
            );
          }
          if (
            componentname.indexOf(item.path) == -1 &&
            routers[routers.findIndex(v => v.name === item.name)].children
              .length == 0
          ) {
            routers.splice(
              routers.findIndex(v => v.name === item.name),
              1
            );
          }
        });
      }

      function getMenuCode(menu) {
        var menus = [];
        if (menu && menu.length > 0) {
          menu.forEach(element => {
            menus.push(element.Url);
            if (element.Childrens && element.Childrens.length > 0) {
              menus = menus.concat(getMenuCode(element.Childrens));
            } else {
              return [];
            }
          });
        }
        return menus;
      }
      var menus = getMenuCode(options.menus);
      eachSelect(defaultRouter, menus);
      commit("setRouters", addRouter);
    }
  }
};

export default routerData;

执行顺序:newRoutes=>路由无值=>getMenuCode=>eachSelect=>commit
想要看懂流程请先了解findIndex,indexOf,splice

四、登录时保存路由数据

login() {
      let that = this;
      var data = {
        Tel: that.tel,
        VerificationCode: that.verificationCode
      };
      this.loading = true; //改变loading状态
      Sign(data).then(res => { //调用登录接口
          if (res.Status) { //成功获取参数后
            that.$store.dispatch("setToken", "asdasdasdsad"); //随便写的token验证,可以忽略
            that.$store.dispatch("setRole", { //调用vuex中的方法,保存用户信息
              UserID: res.Data.UserId,
              Menus: res.Data.Menus
            });
            that.$router.push({ path: "/index" });
            this.$notify({
              title: "成功",
              message: "登录成功",
              type: "success"
            });
          } else {
            this.$notify.error({
              title: "错误",
              message: res.Message
            });
          }
          this.loading = false;
        })
        .catch(err => {
          this.$notify.error({
            title: "错误",
            message: "参数获取失败,请重试"
          });
          this.loading = false;
        });
    },

保存用户信息方法

setRole(state, options) {
      // 切换角色,测试权限管理
      state.info = {
        UserID: options.UserID,
        Menus: options.Menus
      };
      sessionStorage.setItem("info", JSON.stringify(store.getters.info)); //保存用户信息到缓存
      store.dispatch("newRoutes", { //调用动态生成路由方法
        menus: options.Menus,
        role: options.RoleName
      });
      router.addRoutes(store.getters.addRouters);//这里是添加无需验证的动态路由
    },

五、在main.js中设置路由守卫,防止刷新路由消失

router.beforeEach((to, from, next) => {
  if (store.getters.token) { //判断是否登录
    store.dispatch("setToken", store.getters.token);
    if (to.path === "/login") {
      Cookies.remove("token");
      next();
      return;
    } else {
      if (to.matched.length) { //判断输入的路由在路由表中是否存在
        !(async function getAddRouters() {
          await store.dispatch("newRoutes", { //动态设置路由
            menus: store.getters.info.Menus,
            role: store.getters.info.RoleName
          });
        })();
        next();
      } else {
        next({
          path: "/404"
        });
      }
    }
  } else {
    if (to.path === "/login") {
      next();
    } else {
      next({
        path: "/login"
      });
    }
  }
});

在vuex中获取info的问题

state: {
    info: JSON.parse(sessionStorage.getItem("info")) || "", // 从缓存中取或者是为空(登录或者未登录)
  },

六、流程简述

1、用户登录
2、保存返回的用户信息和权限路由(vuex和缓存)
3、触发路由守卫,调用路由筛选
4、根据数据,删除无权限的路由信息
5、返回筛选后的路由信息
6、渲染路由和页面
7、刷新触发3-6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值