vue实现权限控制2(转载)
转载:https://www.jianshu.com/p/207c3b0cde69
几种方案
对于后端返回来可选则的权限方案:
- plan1(branch:plan1): 返回路由 name 的是否可访问的表,例如:
{page1:true,page2:true,page3:false}
- plan2(branch:plan2): 返回权限级别,比如:
['admin','admin-delete','page1-all']
,我们可以在路由表的 meta 中匹配角色 - plan3(branch:plan3): 返回完整的路由表,例如:
{[{path: "/",name: "Home",component: 'Home',},}
,不能返回绝对路径,要返回 Home
方案一:后端返回此用户可以访问的路由的name的表
代码如下
src/router/index
import basicsRoutes from "./module/basicsRoutes"; import { setTitle } from "../utils/router"; import store from "../store"; Vue.use(VueRouter); const router = new VueRouter({ mode: "history", base: process.env.BASE_URL, basicsRoutes, }); router.beforeEach((to, from, next) => { to.meta && setTitle(to.meta.title); let token = "..."; if (token) { if (!store.state.router.hasGetRules) { // store // .dispatch("authorization") // .then((rules) => { // 这里为后端返回的路由name的权限表 const rules = { Form: true, List: false, About: true }; // 在store 中处理生成完整的路由表 store .dispatch("concatRoutes", rules) .then((routers) => { // 合并路由表 router.addRoutes(routers); next({ ...to, replace: true }); }) .catch(() => { next({ name: "login" }); }); // }) // .catch(() => { // token = ''; // next({ name: "login" }); // }); } else { next(); } } else { if (to.name === "login") next(); else next({ name: "login" }); } }); export default router;
src/store/module/router
// 带权限的路由 import asyncRoutes from "../../router/module/asyncRoutes"; // 基础的路由 import basicsRoutes from "../../router/module/basicsRoutes"; const state = { routers: basicsRoutes,// 这里是[]也没事 hasGetRules: false, }; const mutations = { CONCAT_ROUTES(state, routerList) { // 这里要注意路由表的前后问题 state.routers = routerList.concat(basicsRoutes); state.hasGetRules = true; }, }; const getAccesRouterList = (basicsRoutes, rules) => { return basicsRoutes.filter((item) => { if (rules[item.name]) { // 如果有子路由,就进行递归操作 if (item.children) item.children = getAccesRouterList(item.children, rules); return true; } else return false; }); }; const actions = { concatRoutes({ commit }, rules) { console.log(rules); return new Promise((resolve, reject) => { try { let routerList = []; // console.log(Object.entries(rules)); /* ["Form", true] ["List", false] ["About", false] */ // 如果所有页面都可以进行访问,则直接进行返回所有路由 if (Object.entries(rules).every((item) => item[1])) { routerList = asyncRoutes; } else { // 递归asyncRoutes,看哪些页面有权限访问 routerList = getAccesRouterList(asyncRoutes, rules); } commit("CONCAT_ROUTES", routerList); resolve(state.routers); } catch (err) { reject(err); } }); }, }; export default { state, mutations, actions, };
方案二:后端返回此用户的权限级别
代码如下
src/router/index
... // 省略其他代码,详细代码见github:https://github.com/HYzihong/vue2-router-permissions router.beforeEach((to, from, next) => { to.meta && setTitle(to.meta.title); let token = "..."; if (token) { if (!store.state.router.hasGetRules) { // store // .dispatch("authorization") // .then((rules) => { const rules = ["about"]; // 这里传入是用户的权限级别 store .dispatch("concatRoutes", rules) .then((routers) => { console.log(JSON.stringify(routers)); router.addRoutes(routers); next({ ...to, replace: true }); }) .catch(() => { next({ name: "login" }); }); // }) // .catch(() => { // token = ''; // next({ name: "login" }); // }); } else { next(); } } else { if (to.name === "login") next(); else next({ name: "login" }); } });
src/store/module/router
... // 省略其他代码,详细代码见github:https://github.com/HYzihong/vue2-router-permissions const isRoleTrue = (role, rules) => { // 判断这个路由中的meta中的role的中是否包含此权限, return role.filter((_role) => rules.indexOf(_role) > -1).length > 0; }; const getAccesRouterList = (basicsRoutes, rules) => { return basicsRoutes.filter((item) => { if (isRoleTrue(item.meta.role, rules)) { // 如果有子路由,就进行递归操作 if (item.children) item.children = getAccesRouterList(item.children, rules); return true; } else return false; }); }; const actions = { concatRoutes({ commit }, rules) { return new Promise((resolve, reject) => { try { let routerList = []; // 如果是admin权限,则直接进行返回所有路由 if (rules.indexOf("admin") > -1) { routerList = asyncRoutes; } else { // 递归asyncRoutes,看是否有权限访问 routerList = getAccesRouterList(asyncRoutes, rules); } commit("CONCAT_ROUTES", routerList); resolve(state.routers); } catch (err) { reject(err); } }); }, };
方案三:后端返回此用户的可以访问的所有的路由表
代码如下
src/router/index
router.beforeEach((to, from, next) => { to.meta && setTitle(to.meta.title); let token = "..."; if (token) { if (!store.state.router.hasGetRules) { // store // .dispatch("authorization") // .then((rules) => { store .dispatch("concatRoutes") .then((routers) => { console.log(routers); router.addRoutes(routers); next({ ...to, replace: true }); }) .catch(() => { next({ name: "login" }); }); // }) // .catch(() => { // token = ''; // next({ name: "login" }); // }); } else { next(); } } else { if (to.name === "login") next(); else next({ name: "login" }); } });
src/store/module/router
import ajaxRouter from "../../utils/ajaxRouter"; import routerMap from "../../utils/routerMap"; // 方案一:简单的view结构使用 const returnView = (url) => { return () => import(`../../views/${url}.vue`); }; const initRoute = (router) => { router.component = returnView(router.component); if (router.children) getAccesRouterList(router.children); return router; }; // 方案二:复杂的view结构使用 const initRoute = (router) => { router.component = routerMap[router.component]; if (router.children) getAccesRouterList(router.children); return router; }; const getAccesRouterList = (ajaxRouter) => { return ajaxRouter.map((item) => initRoute(item)); }; const actions = { concatRoutes({ commit }) { return new Promise((resolve, reject) => { try { let routerList = []; routerList = getAccesRouterList(ajaxRouter); commit("CONCAT_ROUTES", routerList); console.log(routerList); resolve(state.routers); } catch (err) { reject(err); } }); }, };
src/utils/ajaxRouter
// 模拟后端返回的路由表 const ajaxRouter = [ { path: "/form", name: "Form", component: "Form", }, { path: "/about", name: "About", component: "About", children: [ { path: "aboutChild", name: "AboutChild", component: "AboutChild", }, ], }, { path: "/list", name: "List", component: "List", }, ]; export default ajaxRouter;
src/utils/routerMap.js
// 对应的view文件 import Form from "../views/Form.vue"; import About from "../views/About.vue"; import AboutChild from "../views/AboutChild.vue"; import List from "../views/List.vue"; const routerMap = { Form: Form, About: About, List: List, AboutChild: AboutChild, }; export default routerMap;
作者:HHHHy2019
链接:https://www.jianshu.com/p/207c3b0cde69
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
2019-12-23 python上下文小记
2019-12-23 python合并两个字典
2019-12-23 python小技巧之把list组合成chain
2019-12-23 airflow自动生成dag