管理系统权限管理

思路:

  1. 通过登录不同用户向后台请求不同的权限数据
  2. 对用户权限做对比:请求数据 -对比- 全部路由

准备路由 (src/router/index.js)

import Vue from "vue";
import VueRouter from "vue-router";
const Login = () => import("@/views/login");
const Layout = () => import("@/components/layout/home");
const Home = () => import("@/views/home");
const NotFound = () => import("@/views/errPage/404");

Vue.use(VueRouter);

// 捕获 push replace 中的错误
// 当然在 replace 中的错误也是可以相同的进行捕获
const originalPush = VueRouter.prototype.push;
const originalReplace = VueRouter.prototype.replace;
// push
VueRouter.prototype.push = function push(location, onResolve, onReject) {
  if (onResolve || onReject)
    return originalPush.call(this, location, onResolve, onReject);
  return originalPush.call(this, location).catch((err) => err);
};
// replace
VueRouter.prototype.replace = function push(location, onResolve, onReject) {
  if (onResolve || onReject)
    return originalReplace.call(this, location, onResolve, onReject);
  return originalReplace.call(this, location).catch((err) => err);
};

// 初始化路由
export default new VueRouter({
  routes: [
    {
      path: "/login",
      name: "login",
      component: Login,
      meta: {
        title: "登录",
      },
    },
  ],
});

// 动态路由
export const DynamicRoutes = [
  {
    path: "",
    name: "container",
    redirect: "/home",
    component: Layout,
    meta: {
      requiresAuth: true, // 是否需要登录
      title: "首页",
    },
    children: [
      {
        path: "/home",
        name: "home",
        component: Home,
        meta: {
          title: "首页",
          icon: "el-icon-s-home",
        },
      },
    ],
  },
  {
    path: "*",
    name: "404",
    component: NotFound,
  },
];

准备动态路由列表 (src/router/dynamicRouter.js)

const dynamicRouter = [{
	path: '/resident',
	name: 'resident',
	component: () => import('@/views/resident/index.vue'),
	meta: {
		title: '用户管理',
		icon: 'el-icon-user',
		showMobile: true
	},
	children: [{
		path: '/resident-list',
		name: 'resident-list',
		component: () => import('@/views/resident/resident.vue'),
		meta: {
			title: '用户列表',
			showMobile: true
		}
	}
}
...
]

export default dynamicRouter

封装过滤函数 (src/utils/recursion-router.js)

/**
 *
 * @param  {Array} userRouter 后台返回的用户权限json
 * @param  {Array} allRouter  前端配置好的所有动态路由的集合
 * @return {Array} realRoutes 过滤后的路由
 */

export function recursionRouter(userRouter = [], allRouter = []) {
    var realRoutes = allRouter
        .filter(item => userRouter.includes(item.name))
        .map(item => ({
            ...item,
            children: item.children
                ? recursionRouter(userRouter, item.children)
                : null
        }))
    return realRoutes
}


/**
 *
 * @param {Array} routes 用户过滤后的路由
 *
 * 递归为所有有子路由的路由设置第一个children.path为默认路由
 */
export function setDefaultRoute(routes) {
    routes.forEach((v, i) => {
        if (v.children && v.children.length > 0) {
            v.redirect = { name: v.children[0].name }
            setDefaultRoute(v.children)
        }
    })
}

权限设置(使用vuex管理)

import router, { DynamicRoutes } from "@/router";
import dynamicRoute from '@/router/dynamicRoute'
import { recursionRouter, setDefaultRoute } from '@/utils/recursion-router'

export default {
    namespaced: true,
    state: {
        permissionList: null, /** 所有路由 */
        sidebarMenu: [], /** 导航菜单 */
        currentMenu: '', /** 当前active导航菜单 */
    },
    getters: {},
    mutations: {
        SET_PERMISSION(state, routes) {
            state.permissionList = routes;
        },
        CLEAR_PERMISSION(state) {
            state.permissionList = null;
        },
        SET_MENU(state, menu) {
            state.sidebarMenu = menu;
        },
        CLEAR_MENU(state) {
            state.sidebarMenu = [];
        },
        SET_CURRENT_MENU(state, currentMenu) {
			state.currentMenu = currentMenu;
		}
    },

    // 异步访问
    actions: {
        async FETCH_PERMISSION({ commit, state }) {
            let permissions = ['testA', 'testB', 'testC', 'child_c_a', 'child_c_b']; // 接口获取,与路由名称 name 匹配
            localStorage.setItem('permissions', permissions)
            // 筛选
            let routes = recursionRouter(permissions, dynamicRoute);
            let MainContainer = DynamicRoutes.find(v => v.path === ''); // 找到path == ''的路由
            let children = MainContainer.children;
            children.push(...routes)

            // 生成菜单
            commit('SET_MENU', children);

            // 设置默认路由
            setDefaultRoute([MainContainer]);
            // 初始化路由
            let initialRoutes = router.options.routes;
            DynamicRoutes.forEach(item => {
                router.addRoute(item)
            })
            commit('SET_PERMISSION', [...initialRoutes, ...DynamicRoutes]);
        }
    }
}

路由守卫设置

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";

Vue.use(ElementUI);

Vue.config.productionTip = false;

/* 
    路由权限业务:
        1. 定义全部路由地址
        2. 通过登录不同用户向后台请求不同的权限数据
        3. 对用户权限做对比: 请求数据 -对比- 全部路由
*/
router.beforeEach((to, from, next) => {
  const token = localStorage.getItem("token");
  if (!token) {
    // 用户未登录
    // 页面是否需要登录
    if (
      to.matched.length > 0 &&
      !to.matched.some((record) => record.meta.requiresAuth)
    ) {
      // 页面不需要登录
      next();
    } else {
      // 需要登录
      next({
        path: "/login",
      });
    }
  } else {
    // 用户已登录 处理路由的访问权限
    // 没有权限
    if (!store.state.permission.permissionList) {
      store.dispatch("permission/FETCH_PERMISSION").then(() => {
        next({
          path: to.path,
        });
      });
    } else {
      // store存在权限
      if (to.path !== "/login") {
        next();
      } else {
        next(from.fullPath);
      }
    }
  }
});

router.afterEach((to, from, next) => {
  var routerList = to.matched;
  store.commit("setCrumbList", routerList);
  store.commit("tags/setTags", to);
  store.commit("permission/SET_CURRENT_MENU", to.path);
});

new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值