(十六)VUE权限菜单之动态路由 |
您所在的位置:网站首页 › vueelementui动态菜单 › (十六)VUE权限菜单之动态路由 |
新手做毕设-后台管理系统
任务十四 [VUE权限菜单之菜单管理](https://blog.csdn.net/wdyan297/article/details/128759641)任务十五 [VUE权限菜单之角色管理](https://blog.csdn.net/wdyan297/article/details/128759644)任务十六 VUE权限菜单之动态路由涉及到的实体类1. 用户实体类User2. 菜单实体类Menu3.角色实体类 Role4. 角色菜单实体类RoleMenu5. 登录用户类UserDTO
一、后端登录接口1. 修改userService类中的login方法
二、前端登录页面login.vue完整代码
三、动态路由index.js1. 修改router里的index.js2. 修改Aside组件
四、vue全局状态管理1.安装vuex2. 在src下新建文件夹store,并在文件夹中新建文件index.js3. 在main.js中引用,并添加到组件中4.引用
五、运行项目1. 登录2.菜单管理-新增一级菜单3.菜单管理-新增两个子菜单4.角色管理5.新增一个Test1.vue组件6.保存重新运行登录
任务总结
任务十四 VUE权限菜单之菜单管理
任务十五 VUE权限菜单之角色管理
任务十六 VUE权限菜单之动态路由
在任务十四中完成了权限菜单的菜单管理,主要实现了一级、二级等菜单的添加。任务十五中完成了权限菜单的角色管理,主要实现了角色增删改查已经为角色分配权限菜单。这些基本内容完成之后,就需要做本次任务的内容,即根据登录用户的角色进行动态路由分配,通过本次任务,大家能够: (1)理解用户认证、授权的概念; (2)学会登录验证以及基于网页的HTML5浏览器存储localStorage,存储用户信息和用户授权菜单; (3)掌握动态路由设计; (4)学会登录login基本方法。 首先梳理一下整个逻辑; (1)用户登录需要做两件事,一件事是验证用户的合法性,设置TOKEN,然后将信息进行浏览器存储;另一件事是得到这个合法用户的role(也就是角色标识,如ROLE_ADMIN),根据这个角色标识获取到角色ID,根据角色ID获取权限菜单。 (2)获取到权限菜单后,只是一个列表,在确保确实是menu表中的数据之外,还需要与menu表中数据进行匹配,对每一个menuid判断出它是一级菜单还是二级菜单; (3)将权限菜单数据同样进行浏览器存储; (4)用户验证合法、获取授权菜单后登录,进入主页面,原先固定的Aside组件需要根据动态存储的menus值重新设置。 涉及到的实体类表结构为: 基于任务十三 JWT+SpringSecurity实现基于Token的登录修改userService类中添加login方法。 package com.example.demo.service; import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.demo.common.Constants; import com.example.demo.controller.dto.UserDTO; import com.example.demo.entity.Menu; import com.example.demo.entity.User; import com.example.demo.exception.ServiceException; import com.example.demo.mapper.RoleMapper; import com.example.demo.mapper.RoleMenuMapper; import com.example.demo.mapper.UserMapper; import com.example.demo.utils.TokenUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; @Service public class UserService extends ServiceImpl{ private UserMapper userMapper; @Resource private RoleMenuMapper roleMenuMapper; @Resource private RoleMapper roleMapper; @Resource private MenuService menuService; public Boolean saveUser(User user) { return saveOrUpdate(user); } public UserDTO login(UserDTO userDTO) { QueryWrapper queryWrapper=new QueryWrapper(); queryWrapper.eq("username",userDTO.getUsername()); queryWrapper.eq("password",userDTO.getPassword()); User one; try{ one=getOne(queryWrapper); }catch (Exception e){ throw new ServiceException(Constants.CODE_500,"系统错误");//这里假设查询了多于1条记录,就让他报系统错误 } if(one!=null){ //以下是登录判断业务 BeanUtil.copyProperties(one,userDTO,true); //设置token String token=TokenUtils.genToken(one.getId().toString(),one.getPassword().toString()); userDTO.setToken(token); String role=one.getRole();//查询出用户的角色标识,比如ROLE_ADMIN //设置用户的菜单列表 List roleMenus=getRoleMenus(role); userDTO.setMenus(roleMenus); return userDTO; }else { throw new ServiceException(Constants.CODE_600,"用户名或密码错误"); } } /** * 获取当前用户的菜单列表 */ private List getRoleMenus(String roleFlag){ //根据角色标识获取角色Id Integer roleId=roleMapper.selectByflag(roleFlag); //当前角色Id的所有菜单id集合 List menuIds=roleMenuMapper.selectByRoleId(roleId); //查出系统所有菜单 List menus=menuService.findMenus(""); //筛选当前用户菜单 List roleMenus=new ArrayList(); for(Menu menu:menus){ if(menuIds.contains(menu.getId())){ roleMenus.add(menu); } List children=menu.getChildren(); //removeIf移除children里面不在menuIds集合中的元素 children.removeIf(child->!menuIds.contains(child.getId())); } return roleMenus; } }其中涉及到的方法在任务十四和任务十五中均有,如果前面没有做的童鞋,可以在前面的任务中找到。 roleMapper.selectByflag(roleFlag);在任务十五有详细讲解,完整代码为: package com.example.demo.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.demo.entity.Role; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; public interface RoleMapper extends BaseMapper { //根据角色唯一标识flag查找角色id @Select("select id from sys_role where flag=#{flag}") Integer selectByflag(@Param("flag") String role); }roleMenuMapper.selectByRoleId(roleId);在任务十五有详细讲解,完整代码为: package com.example.demo.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.demo.entity.RoleMenu; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.util.List; public interface RoleMenuMapper extends BaseMapper { //根据角色id删除角色菜单数据 @Delete("delete from sys_role_menu where role_id=#{roleId}") int deleteByRoleId(@Param("roleId") Integer roleId); //根据角色id查找菜单id @Select("select menu_Id from sys_role_menu where role_id=#{roleId}") List selectByRoleId(@Param("roleId") Integer roleId); }menuService.findMenus(“”);在任务十四有详细讲解,完整代码为: package com.example.demo.service; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; importcom.example.demo.entity.Menu;; import com.example.demo.mapper.MenuMapper; import org.springframework.stereotype.Service; import java.util.List; import java.util.stream.Collectors; @Service public class MenuService extends ServiceImpl { public List findMenus(String name) { QueryWrapper queryWrapper=new QueryWrapper(); if(StrUtil.isNotBlank(name)){ queryWrapper.like("name",name); } List list = list(queryWrapper); // 找出pid为null的一级菜单 List parentNodes=list.stream().filter(menu -> menu.getPid()==null).collect(Collectors.toList()); //找出一级菜单为null的二级菜单放到Children中 for(Menu menu:parentNodes){ menu.setChildren(list.stream().filter(m->menu.getId().equals(m.getPid())).collect(Collectors.toList())); } System.out.println(parentNodes); return parentNodes; } } 二、前端登录页面 login.vue完整代码这个页面与任务十三登录页面没有太多大的改动,因为那里已经实现了基于Token的认证,并且保存了用户信息。 继续添加一个获取菜单的接口即可。 完整代码如下: 登录 登录 重置 import {setRoutes} from "@/router"; import {resetRouter} from "@/router"; export default { name: "Login", data() { return { loginForm: { username:'', password:'' }, LoginFormRules:{ username:[ { required: true, message: '请输入用户名', trigger: 'blur' }, ], password:[ { required: true, message: '请输入密码', trigger: 'blur' }, ] } } }, methods:{ login(){ this.$refs['LoginFormRef'].validate(async (valid) => { if (valid) { this.request.post("http://localhost:8084/user/login",this.loginForm).then(res=>{ if(res.code=='200'){ localStorage.setItem("user",JSON.stringify(res.data));//存储用户信息到浏览器 localStorage.setItem("menus",JSON.stringify(res.data.menus));//存储用户权限菜单信息到浏览器 //动态设置当前用户的路由 setRoutes() this.$router.push("/home"); this.$message.success("登录成功"); }else{ this.$message.error(res.msg); } }) } }) }, resetLoginForm(){ this.$refs.LoginFormRef.resetFields() } } } .login_container{ background-color: #2b4b6b; height: 100%; } .login_box{ width: 350px; height: 300px; background-color: #fff; border-radius: 3px; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%) } >
任务十VUE侧边菜单栏导航 中我们修改过VUE侧边菜单栏导航,但那时候还是固定的。现在根据动态路由生成侧边菜单栏。 完整代码如下: ![]() 理解 的重点就是根据已存储的menus动态部署侧栏。 四、vue全局状态管理对于一些全局变量或者方法,可以进行全局设置,然后在任何时候都可以直接使用。比如常用的登出logout方法等。 具体方法为: 1.安装vuex npm install vuex --save安装完成后注意观察一个vuex的版本。 vuex分3.x版本和4.x版本,分别对应vue2.0与3.0。 这里用的是VUE2.0,所以需要vuex是3.x版本。具体安装方法也可以到网上查找。
新增代码段如下: import store from './store/index' new Vue({ router, store,//定义成全局变量 render: h => h(App) }).$mount('#app')比如在任务十五中当判断给管理员重新分配了权限,就需要重新登录,这时候先登出,就调用store中的logout方法。 为管理员角色分配菜单
本次任务完成后,整个项目将根据不同用户部署不同菜单,实现动态路由,而且,只要有新的页面生成,只要添加到菜单中即可,就可以实现动态访问。 通过本次任务,大家能够: (1)理解动态路由的概念; (2)VUE对整个框架的管理机制有所了解; (3)学会VUE 状态管理定义与使用。 下一个任务将使用Echart做一个简单Home页面。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |