黄沙百战穿金甲,不破楼兰终不还。这篇文章主要讲述系统管理前端开发-02相关的知识,希望能为你提供帮助。
登陆之后加载菜单和后台关联问题加载菜单方案选择
方案概述
- 在使用过程中有这样一个问题,vue-element-admin 的菜单列表是通过遍历路由进行渲染的,由前端定义,可以在 router.js 中看到相关代码,其实路由也是菜单。
- 好处是我们不用重复定义菜单列表信息和路由之间的绑定了;但是我们的菜单信息想通过服务端进行动态输出来达到权限控制的效果就不是那么容易了。
- 现在很多解决方案是由服务端输出完整的 vue-element-admin 路由信息并进行绑定,这样虽然能达到动态菜单的效果,但是给服务端也造成了不必要的烦恼。
- 作为服务端开发:不关心菜单对应的是哪个 vue 里面的 component ,也不希望将菜单的格式限定得那么严格,甚至不关心菜单的图标是什么,只需要严格按照服务端的要求显示或隐藏菜单即可。
- 为了解决这个问题,我的优化方案如下,服务端只需控制菜单显示或隐藏,路由信息定义都在前端写死,这样达到完美的前后端分离要求。
市面上普遍存在的是第一种方案, 在这里我选用第二种方式。
- 所有的路由地址由后端提供,异步渲染。
- 所有路由前端提供,后台提供数据确定前端哪些路径 (菜单) 隐藏 (不挂载)
开始修改定义路由
- 原因: 作为服务端开发:不关心 菜单对应的是哪个 vue 里面的 component ,也不希望将菜单的格式限定得那么严格,甚至不关心菜单的图标是什么,只需要严格按照服务端的要求显示或隐藏菜单即可。
在 src/router/index.js 中将 constantRoutes 常量中定义的侧边栏显示的菜单信息删除掉;修改 asyncRoutes常量写入菜单信息,asyncRoutes 中每个节点都有 name 属性,通过它来和服务端返回的菜单信息进行关联。
服务端接口
修改用户Api请求src/api/ 目录下的 user.js 添加如下接口
// 加载菜单信息
export& nbsp; function& nbsp; getMenus()& nbsp;
& nbsp; & nbsp; return& nbsp; request(
& nbsp; & nbsp; & nbsp; & nbsp; url:& nbsp; & #39; /login/getMenus& #39; ,
& nbsp; & nbsp; & nbsp; & nbsp; method:& nbsp; & #39; get& #39;
& nbsp; & nbsp; )
配置store调用创建 src/store/modules/menu.js
import& nbsp; & nbsp; asyncRoutes,& nbsp; constantRoutes,& nbsp; lastRoute& nbsp; & nbsp; from& nbsp; & #39; @/router/index& #39;
import& nbsp; & nbsp; getMenus& nbsp; & nbsp; from& nbsp; & #39; @/api/user& #39;
const& nbsp; state& nbsp; =& nbsp;
& nbsp; & nbsp; routes:& nbsp; []
const& nbsp; mutations& nbsp; =& nbsp;
& nbsp; & nbsp; SET_ROUTES:& nbsp; (state,& nbsp; routes)& nbsp; =& gt; & nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; state.routes& nbsp; =& nbsp; routes
& nbsp; & nbsp;
// 动态菜单还是定义在前端,后台只会返回有权限的菜单列表,通过遍历服务端的菜单数据,没有的将对于菜单进行隐藏
// 这样的好处是服务端无需返回前端菜单相关结构,并且菜单显示又可以通过服务端来控制,进行菜单的动态控制
// 前端新增页面也无需先通过服务端进行菜单添加,遵循了前后端分离原则
function& nbsp; generateRoutes(routes,& nbsp; srvMenus)& nbsp;
& nbsp; & nbsp; for& nbsp; (let& nbsp; i& nbsp; =& nbsp; 0; & nbsp; i& nbsp; & lt; & nbsp; routes.length; & nbsp; i++)& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; const& nbsp; routeItem& nbsp; =& nbsp; routes[i]
& nbsp; & nbsp; & nbsp; & nbsp; var& nbsp; showItem& nbsp; =& nbsp; false
& nbsp; & nbsp; & nbsp; & nbsp; for& nbsp; (let& nbsp; j& nbsp; =& nbsp; 0; & nbsp; j& nbsp; & lt; & nbsp; srvMenus.length; & nbsp; j++)& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; const& nbsp; srvItem& nbsp; =& nbsp; srvMenus[j]
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; // 前后端数据通过 serPath 属性来匹配
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; if& nbsp; (routeItem.name& nbsp; !==& nbsp; undefined& nbsp; & amp; & amp; & nbsp; routeItem.name& nbsp; ===& nbsp; srvItem.serPath& nbsp; & amp; & amp; & nbsp; srvItem.show& nbsp; ===& nbsp; true)& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; showItem& nbsp; =& nbsp; true
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; routes[i][& #39; hidden& #39; ]& nbsp; =& nbsp; false
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; break
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;
& nbsp; & nbsp; & nbsp; & nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; if& nbsp; (showItem& nbsp; ===& nbsp; false)& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; routes[i][& #39; hidden& #39; ]& nbsp; =& nbsp; true
& nbsp; & nbsp; & nbsp; & nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; if& nbsp; (routeItem[& #39; children& #39; ]& nbsp; !==& nbsp; undefined& nbsp; & amp; & amp; & nbsp; routeItem[& #39; children& #39; ].length& nbsp; & gt; & nbsp; 0)& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; generateRoutes(routes[i][& #39; children& #39; ],& nbsp; srvMenus)
& nbsp; & nbsp; & nbsp; & nbsp;
& nbsp; & nbsp;
const& nbsp; actions& nbsp; =& nbsp;
& nbsp; & nbsp; getMenus(& nbsp; commit& nbsp; ,& nbsp; roles)& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; return& nbsp; new& nbsp; Promise(resolve& nbsp; =& gt; & nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; // 查询所端的菜单数据
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; getMenus(state.token).then(async& nbsp; function(res)& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; const& nbsp; srvMenus& nbsp; =& nbsp; res.data
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; var& nbsp; pushRouter& nbsp; =& nbsp; asyncRoutes
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; generateRoutes(pushRouter,& nbsp; srvMenus)
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; const& nbsp; routeArr& nbsp; =& nbsp; []
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; routeArr.push(...constantRoutes)
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; routeArr.push(...pushRouter)
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; routeArr.push(...lastRoute)
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; commit(& #39; SET_ROUTES& #39; ,& nbsp; routeArr)
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; resolve(pushRouter)
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; )
& nbsp; & nbsp; & nbsp; & nbsp; )
& nbsp; & nbsp;
export& nbsp; default& nbsp;
& nbsp; & nbsp; namespaced:& nbsp; true,
& nbsp; & nbsp; state,
& nbsp; & nbsp; mutations,
& nbsp; & nbsp; actions
修改 store/getters.js
动态渲染菜单修改?
?src/permission.js?
?登陆测试, 发现菜单不显示
修改加载菜单取数据的参数, 修改 src/layout/components/Sidebar/index.vue
因为现在动态路由数据是存在到我们自己定义的 VUEX 里面,所以要改, 修改完登陆加载就可以了, 修改数据库测试下
刷新页面, 发现没有检查管理了
【系统管理前端开发-02】
推荐阅读
- 理“ Druid 元数据”之乱
- 监听器
- JDK8
- React-Redux-实现原理
- React-Redux-处理网络数据
- React-Redux的使用
- 后台管理项目页面搭建模板
- 低代码机器人是如何实现监控库存,并实时通知指定人,仓库管理不再慌乱
- 低代码开发的前后端联调——APICloud Studio 3 API管理工具结合数据云3.0使用教程