zoukankan      html  css  js  c++  java
  • 树形菜单

      树形菜单应该是很常见的了,类似下面这种,通常我们的做法是后端从数据库中查询出来数据,然后将其转为树的结构,丢给前端,前端就渲染到树组件中;

      那么返给前端的数据是什么样的呢?如下所示

    [    {
              id: 1,
              label: '一级 1',
              children: [{
                id: 4,
                label: '二级 1-1',
                children: [{
                  id: 9,
                  label: '三级 1-1-1'
                }, {
                  id: 10,
                  label: '三级 1-1-2'
                }]
              }]
            },
        {xxx}
    
    ]    

      那么对应在数据库中的表示什么样子的呢?Subject表下图所示,如果parent_id为0的,表示是一级菜单,其他多个二级菜单的parent_id等于某个一级菜单的id,依次类推,可有有很多级别菜单

    下面用java代码实现

      1.工具类:

    package com.protagonist.edu.utils;
    
    import com.protagonist.edu.bo.SubjectTreeNodeBO;
    import com.protagonist.edu.entity.Subject;
    import com.protagonist.responseVO.StatusCode;
    import com.protagonist.servicebase.exception.ProtagonistException;
    import org.springframework.beans.BeanUtils;
    import org.springframework.util.CollectionUtils;
    
    import java.util.*;
    
    /**
     * 用于构建树形结构
     */
    public class TreeUtil {
        /**
         * 默认树形菜单最顶层的pid是"0"
         * @param list 所有数据
         * @return 树形的数据
         */
        public static  List<SubjectTreeNodeBO> buildTree(List<Subject> list) {
            if (CollectionUtils.isEmpty(list)){
                throw new ProtagonistException(StatusCode.ERROR,"查询的菜单数据为空,不能转为树形");
            }
            return buildTree(list, "0");
        }
    
        /**
         *   获取树形菜单结构
         *      思路:首先遍历一次将所有的数据转化为前端需要的数据类型,然后放入到map中,以id->T对应关系
         *      然后再遍历一次,这次的话判断parentId是否为0(这里暂时可以特使pid为0时表示一级菜单),是的话就是一级菜单,就放到rootTree中;
         *      不为0的话,说明不是一级菜单,我们就需要获取它的父菜单
         *      根据pid去map中获取,然后将当前菜单放入其父菜单的子菜单中,等遍历完之后树形菜单就ok了,这种做法可以完成多级子菜单变成树形
         * @param list 所有的数据
         * @param pid 父id
         * @return 树形数据
         */
        public static  List<SubjectTreeNodeBO> buildTree(List<Subject> list, String pid) {
            if (CollectionUtils.isEmpty(list)){
                throw new ProtagonistException(StatusCode.ERROR,"查询的菜单数据为空,不能转为树形");
            }
            List<SubjectTreeNodeBO> allTreeNode = new ArrayList<>();
            List<SubjectTreeNodeBO> rootTree = new ArrayList<>();
            Map<String, SubjectTreeNodeBO> nodeMap = new HashMap<>();
            //将所有的数据都放入到map中一份
            for (Subject item : list) {
                SubjectTreeNodeBO nodeBO = new SubjectTreeNodeBO();
                BeanUtils.copyProperties(item,nodeBO);
                allTreeNode.add(nodeBO);
                nodeMap.put(item.getId(),nodeBO);
            }
            for (SubjectTreeNodeBO t : allTreeNode) {
                //如果父id等于传进来的pid,那么该菜单是最顶级的菜单,放入到rootTree中
                if (Objects.equals(t.getParentId(), pid)){
                    rootTree.add(t);
                    //如果不是顶级菜单,那就获取父菜单,然后嫁给你本BO设置到父菜单的children中
                }else {
                    SubjectTreeNodeBO parentNode = nodeMap.get(t.getParentId());
                    parentNode.getChildren().add(t);
                }
            }
            return rootTree;
        }
    }

       2.subject类:

    @Data
    @EqualsAndHashCode(callSuper = false)
    @Accessors(chain = true)
    @TableName("subject")
    @ApiModel(value="Subject对象", description="课程科目")
    public class Subject implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @ApiModelProperty(value = "课程类别ID")
        @TableId(value = "id", type = IdType.ID_WORKER_STR)
        private String id;
    
        @ApiModelProperty(value = "类别名称")
        private String title;
    
        @ApiModelProperty(value = "父ID")
        private String parentId;
    
    }
    3.SubjectTreeNodeBO类:
    package com.protagonist.edu.bo;
    
    import lombok.Data;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Data
    public class SubjectTreeNodeBO {
    
        private String id;
    
        private String title;
    
        private String parentId;
    
        private List<SubjectTreeNodeBO> children = new ArrayList<>();
    }

      4. 测试,成功,然后配合element的Tree 树形控件一起使用,就行了

  • 相关阅读:
    docker mysql 主从配置
    在docker上安装运行mysql实例
    mongodb分片集搭建
    mongodb片健的选取及更改
    MySQL 5.7的多源复制
    percona-toolkit使用教程
    Python基础操作-集合
    nginx location 在配置中的优先级
    OpenResty知识汇集
    开源分布式日志框架
  • 原文地址:https://www.cnblogs.com/wyq1995/p/13766717.html
Copyright © 2011-2022 走看看