废话不多说,直接贴代码
首先是需要一个实体类:
@Data
public class Menu {
// 菜单id
private String id;
// 菜单名称
private String menuName;
// 父菜单id
private String parentId;
// 菜单url
private String menuUrl;
// 菜单图标
private String icon;
// 菜单顺序
private int orderNum;
// 子菜单
@TableField(exist = false)
private List<Menu> children;
//是否显示
private String delFlag;
@TableField(fill = FieldFill.INSERT)
private Date createTime;//创建时间
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;//修改时间
}
然后实现方法(service 层)
public Comparator<Menu> order(){
Comparator<Menu> comparator = new Comparator<Menu>() {
@Override
public int compare(Menu o1, Menu o2) {
if (o1.getOrderNum() != o2.getOrderNum()){
return o1.getOrderNum() - o2.getOrderNum();
}
return 0 ;
}
};
return comparator;
}
public List findTree(){
Map<String,Object> data = new HashMap<String,Object>();
//查询所有菜单
List<Menu> allMenu = menuMapper.selectList(null);
//根节点
List<Menu> rootMenu = new ArrayList<Menu>();
for (Menu nav : allMenu) {
if (nav.getParentId().equals( "0" )){ //父节点是0的,为根节点。
rootMenu.add(nav);
}
}
/* 根据Menu类的order排序 */
Collections.sort(rootMenu, order());
//为根菜单设置子菜单,getClild是递归调用的
for (Menu nav : rootMenu) {
/* 获取根节点下的所有子节点 使用getChild方法*/
List<Menu> childList = getChild(nav.getId(), allMenu);
nav.setChildren(childList);//给根节点设置子节点
}
/**
* 输出构建好的菜单数据。
*
*/
data.put( "success" , "true" );
data.put( "list" , rootMenu);
return rootMenu;
}
public List<Menu> getChild(String id,List<Menu> allMenu){
//子菜单
List<Menu> childList = new ArrayList<Menu>();
for (Menu nav : allMenu) {
// 遍历所有节点,将所有菜单的父id与传过来的根节点的id比较
//相等说明:为该根节点的子节点。
if (nav.getParentId().equals(id)){
childList.add(nav);
}
}
//递归
for (Menu nav : childList) {
nav.setChildren(getChild(nav.getId(), allMenu));
}
Collections.sort(childList,order()); //排序
//如果节点下没有子节点,返回一个空List(递归退出)
if (childList.size() == 0 ){
return new ArrayList<Menu>();
}
return childList;
}
然后返回的数据是这样的:
"list": [
{
"id": "1",
"name": "Java",
"parentid": "0",
"url": "http://www.aliouchen.com",
"order": 1,
"children": [
{
"id": "2",
"name": "并发编程",
"parentid": "1",
"url": "http://www.aliouchen.com",
"order": 1,
"children": []
},
{
"id": "3",
"name": "多线程",
"parentid": "1",
"url": "http://www.aliouchen.com",
"order": 2,
"children": [
"id": "4",
"name": "Thread",
"parentid": "3",
"url": "http://www.aliouchen.com",
"order": 1,
"children":[]
]
}
]
},
{
"id": "5",
"name": "Python",
"parentid": "0",
"url": "http://www.aliouchen.com",
"order": 2,
"children": []
}
]
前端实现显示代码(js)
<ul class="djcdWrap"></ul>
<script type="text/javascript" th:inline="javascript">
//th:inline="javascript" 为了获取后台返回的值
var menuArray = [[${menu}]];//那个list菜单数据
$(function () {
loadHtml(menuArray,$("ul.djcdWrap"))
// 点击某一级的菜单进行展开或者隐藏
$("ul span").mouseenter(function () {
$(this).next("ul.son").slideToggle(100);
})
})
function loadHtml(data,dom) {
var child = null;
for(var i=0;i<data.length;i++) {
if(data[i].children.length == 0) {
// 没有子菜单
child = $("<li><a href='"+data[i].menuUrl+"'>"+ data[i].menuName +"</a></li>")
}else {
// 有子菜单
child = $("<li class='active'><span>"+ data[i].menuName +"</span><ul class='son'></ul></li>")
loadHtml(data[i].children,child.find("ul.son"))
}
dom.append(child)
}
}
</script>
借鉴了以下地址的文章:
java:https://www.jb51.net/article/122811.htm
html:https://blog.csdn.net/hhy1006894859/article/details/84936935
记录一下