当前位置:   article > 正文

SpringBoot + Vue 实现侧边栏目录动态展示_vue动态目录

vue动态目录

一、需求

        不同用户拥有不同角色,不同角色拥有不同权限。用户登录之后,要根据用户的不同角色和不同权限,来动态调整侧边栏的展示。

二、数据库设计

        实现功能至少需要这几个表格:

        1、用户信息表(记录UUID或者唯一标示位);

        2、角色表(定义角色唯一ID和角色名称);

        3、权限表(定义各个权限,包括其code、name、path和Parent);

        4、用户—角色表(不同用户对应不同角色);

        5、角色—权限表(不同的角色对应不同的权限)。

三、代码实现思路

        1、前端--->后台(标示用户的唯一ID);

        2、通过唯一ID去“用户—角色表”查询到对应的Role;

        3、通过对应的Role去“角色—权限表”找到与之对应的所有Permissions;

        4、处理获取的Permissions,将之转换为父子级关系的树型结构

        5、将树结构--->前端;

        6、Vue获取树结构,渲染侧边栏。

四、后台实现代码示例(仅关键代码)

Controller:

  1. @GetMapping
  2. public Result getAllPermissionByRole(@RequestParam("gh") String gh){
  3. String roleName = userToRoleService.getRoleByHdgh(gh);
  4. if(!roleName.isEmpty()){
  5. List<PermissionDTO> permissionDTOS = permissionService.getAllPermissionByRole(roleName);
  6. if(!permissionDTOS.isEmpty()){
  7. return new Result(Code.SUCCESS, permissionDTOS, "OK");
  8. }
  9. else {
  10. return new Result(Code.ERROR, null, "Error");
  11. }
  12. }
  13. return new Result(Code.FAILED, null, "Failed");
  14. }

其中:

        role是通过查询用户—角色表,得到的RoleName(此处根据自己业务实现);

        UserToRoleService是用户对应权限表的service;

        PermissionDTO是包含父子级关系的Permission类;

        Result是个人定义的返回结果类。

PermissionDTO:

  1. @Data
  2. public class PermissionDTO {
  3. // 权限ID
  4. private Integer permissionId;
  5. // 权限代码
  6. private String permissionCode;
  7. // 权限名称
  8. private String permissionName;
  9. // 权限全部代码
  10. private String permissionCodeAll;
  11. // 权限路径
  12. private String permissionPath;
  13. // 父级
  14. private Integer permissionParent;
  15. // 子节点
  16. private List<PermissionDTO> children = new ArrayList<>();
  17. /*
  18. * 排序,根据permissionId排序
  19. * 升序
  20. * */
  21. public static Comparator<PermissionDTO> order(){
  22. Comparator<PermissionDTO> comparator = (o1, o2) -> {
  23. if(o1.getPermissionId() != o2.getPermissionId()){
  24. return (int)(o1.getPermissionId() - o2.getPermissionId());
  25. }
  26. return 0;
  27. };
  28. return comparator;
  29. }
  30. }

Permission:

  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. public class Permission {
  5. // 权限ID,主键
  6. @TableId
  7. private Integer permissionId;
  8. // 权限代码
  9. private String permissionCode;
  10. // 权限名称
  11. private String permissionName;
  12. // 权限全部代码
  13. private String permissionCodeAll;
  14. // 权限路径
  15. private String permissionPath;
  16. // 父级
  17. private Integer permissionParent;
  18. // 备注
  19. private String bz;
  20. }

PermissionServiceImpl:(获取全部权限的实现类)

  1. public List<PermissionDTO> getAllPermissionByRole(String role) {
  2. // 先获取与role对应的所有Permissions
  3. List<Permission> permissions = permissionDao.getAllPermissionByRole(role);
  4. // 将获取的Permissions 转换成 PermissionDTO类型(包含children的那种)
  5. if(!CollectionUtils.isEmpty(permissions)){
  6. List<PermissionDTO> permissionDTOS = new ArrayList<>();
  7. permissionDTOS = PermissionConverter.permission2permissionDTO(permissions);
  8. // 转换为PermissionDTO树类型
  9. return PermissionTreeBuilder.build(permissionDTOS);
  10. }
  11. return null;
  12. }

此处涉及两个方法:

1、permission2permissionDTO(),这是一个转换类,将没有children的Permission转换为带有children的PermissionDTO,方便生成树结构。

2、PermissionTreeBuilder(),这是一个通过递归方法,将PermissionDTO生成一个树结构的List。

permission2permissionDTO:

  1. public static List<PermissionDTO> permission2permissionDTO(List<Permission> permissions){
  2. List<PermissionDTO> permissionDTOS = new ArrayList<>();
  3. if(!CollectionUtils.isEmpty(permissions)){
  4. for(Permission permission:permissions){
  5. if(!Objects.equals(permission.getPermissionPath(), "null")){
  6. PermissionDTO permissionDTO = new PermissionDTO();
  7. BeanUtils.copyProperties(permission, permissionDTO);
  8. permissionDTOS.add(permissionDTO);
  9. }
  10. }
  11. }
  12. return permissionDTOS;
  13. }

PermissionTreeBuilder:

  1. public class PermissionTreeBuilder {
  2. /**
  3. * 构建多级菜单树
  4. * @param nodes
  5. * @return List<PermissionDTO>
  6. */
  7. public static List<PermissionDTO> build(List<PermissionDTO> nodes){
  8. // 根节点
  9. List<PermissionDTO> rootMenu = new ArrayList<>();
  10. for(PermissionDTO permissionDTO:nodes){
  11. if(permissionDTO.getPermissionParent() == 0){
  12. rootMenu.add(permissionDTO);
  13. }
  14. }
  15. // 根据PermissionDTO类的order进行从小到大排序
  16. Collections.sort(rootMenu, PermissionDTO.order());
  17. // 为根节点设置子节点,getChild递归调用
  18. for(PermissionDTO permissionDTO:rootMenu){
  19. // 获取根节点下的所有子节点 使用下面getChild方法
  20. List<PermissionDTO> childList = getChild(permissionDTO.getPermissionId(), nodes);
  21. // 给根节点设置子节点
  22. permissionDTO.setChildren(childList);
  23. }
  24. return rootMenu;
  25. }
  26. /**
  27. * 获取子目录节点
  28. * @param id
  29. * @param nodes
  30. * @return List<PermissionDTO>
  31. */
  32. private static List<PermissionDTO> getChild(Integer id, List<PermissionDTO> nodes){
  33. // 子菜单
  34. List<PermissionDTO> childList = new ArrayList<>();
  35. for(PermissionDTO permissionDTO:nodes){
  36. // 遍历所有节点,将所有菜单的父ID与传过来的根节点ID比较,相等说明为该根节点的字节点
  37. if(permissionDTO.getPermissionParent().equals(id)){
  38. childList.add(permissionDTO);
  39. }
  40. }
  41. // 递归
  42. for(PermissionDTO permissionDTO:childList){
  43. permissionDTO.setChildren(getChild(permissionDTO.getPermissionId(), nodes));
  44. }
  45. // 根据所有PermissionDTO类的order进行从小到大排序
  46. Collections.sort(childList, PermissionDTO.order());
  47. // 如果节点下面没有子节点,返回一个空的List
  48. if(childList.size() == 0){
  49. return new ArrayList<>();
  50. }
  51. return childList;
  52. }
  53. }

至此,后台部分宣告完毕。

五、 Vue 2.x实现示例

创建一个component:

  1. <template>
  2. <div>
  3. <template v-for="item in this.menuList">
  4. <el-submenu :index="item.permissionId+''" v-if="item.children.length>0" :key="item.permissionId+''">
  5. <template slot="title" style="padding-left:10px">
  6. <span slot="title">{{item.permissionName}}</span>
  7. </template>
  8. <MenuTree :menuList="item.children"></MenuTree>
  9. </el-submenu>
  10. <el-menu-item
  11. v-else
  12. :index="item.permissionPath+''"
  13. :route="item.permissionPath"
  14. @click="savePath(item.permissionPath)"
  15. :key="item.permissionId+''"
  16. style="padding-left: 50px;"
  17. >
  18. <span>{{item.permissionName}}</span>
  19. </el-menu-item>
  20. </template>
  21. </div>
  22. </template>
  23. <script>
  24. export default {
  25. name: "MenuTree",
  26. beforeMount() {},
  27. props: ["menuList"],
  28. methods:{
  29. savePath(path){
  30. localStorage.setItem("activePath", path);
  31. this.activePath = path;
  32. }
  33. },
  34. created(){
  35. }
  36. }
  37. </script>
  38. <style scoped>
  39. </style>

将此组件,插入到页面侧边栏的布局之中,

<MenuTree  :menuList="this.menuList"></MenuTree>

在此处需要往组件里传入menuList值,可以通过axios请求来获取此值,当然此处的用户ID需要自己根据实际情况来获取。

axios发送get请求获取menuList(仅供参考):

  1. getMenu(){
  2. axios.get("/permissions",{
  3. params:{
  4. gh:localStorage.getItem("gh")
  5. }
  6. }).then((res)=>{
  7. // 根据自己封装后台的返回值
  8. this.menuList = res.data.data
  9. })
  10. }

至此基本就可以实现根据用户角色,来展示出不同的侧边栏,实现前端的权限控制。 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/579898
推荐阅读
相关标签
  

闽ICP备14008679号