layui递归生成多级菜单

两种方式,前端直接读取已有的json文件或者请求后端来动态生成json数据。
首先把js贴上。

//dynamicMenu.js  主要的js文件

;(function($) {
    var SidebarMenu = function($element, options) {
    	this.$element = $element;
        this.options = $.extend({}, $.fn.sidebarMenu.defaults, options);
        
        this.init();
    };

    SidebarMenu.prototype.init = function() {
    	var $element = this.$element;
        var options = this.options;
        var initMenu = this.initMenu;
        if (options.data) {
            initMenu($element, options.data);
        } else {
            if (!options.url)
                return;
            $.getJSON(options.url, options.param, function(data2) {
                initMenu($element, data2);
            });
        }
    };

    SidebarMenu.prototype.initMenu = function(target, data) {
        $.each(data, function() {
            var $li = $("<li class='layui-nav-item layui-bg-cyan'></li>");
            var $a = $("<a href='javascript:;'></a>").text(this.a.title);
            var $dl = $("<dl class='layui-nav-child'></dl>");
            $li.append($a);
            $li.append($dl);
            target.append($li);
            menu($a, this.dl, $dl);
        });
    };

    SidebarMenu.prototype.menu = function($a, dl, $dl) {
        var ddArrObj = dl.dd;
        $.each(ddArrObj, function() {
            var $a_ = $("<a></a>", this.a).text(this.a.title);
            var $dl_ = $("<dl class='layui-nav-child'></dl>");
            var $dd_ = $("<dd></dd>");
            $dd_.append($a_);
            $dl.append($dd_);
            if (this.a.leaf)
                return true;
            $a_.attr("href", "javascript:;");
            $dd_.append($dl_);
            menu($a_, this.dl, $dl_);
        });
    };

    var menu = SidebarMenu.prototype.menu;

    $.fn.sidebarMenu = function(options) {
        return this.each(function() {
            new SidebarMenu($(this),options);
        });
    };

    $.fn.sidebarMenu.defaults = {
        url: null,
        param: null,
        data: null
    };
}
)(jQuery);

调用:

//desktop.js  显示菜单
$(function() {
    $('ul#side-menu').sidebarMenu({
        data:ssh_menu_routes  //这种形式是前端直接读取已有的json文件
      //url: '/ssh/base/person-jsonMenu'  //这种形式是请求后端来动态生成json数据,使用一种方式即可
    });
});

前端已有的json文件:

var ssh_menu_routes = [{
    "a": {
        "leaf": false,
        "title": "系统管理",
        "id": 100,
    },
    "dl": {
        "dl-id": "xx",
        "dd": [{
            "a": {
                "leaf": true,
                "title": "主页展示",
                "id": 1001,
                "href": "#",
                "data-id": 1001,
                "data-url": "/ssh/templates/home.html",
                "class": "site-demo-active",
            }
        }, {
            "a": {
                "leaf": true,
                "title": "账号信息",
                "id": 1002,
                "href": "#",
                "data-id": 1002,
                "data-url": "/ssh/base/person-account",
                "class": "site-demo-active",
            }
        }, {
            "a": {
                "leaf": true,
                "title": "我的博客",
                "id": 1003,
                "href": "#",
                "data-id": 1003,
                "data-url": "/ssh/base/blog-query",
                "class": "site-demo-active",
            }
        }, {
            "a": {
                "leaf": true,
                "title": "实时聊天",
                "id": 1004,
                "href": "#",
                "data-id": 1004,
                "data-url": "/ssh/templates/chat.jsp",
                "class": "site-demo-active",
            }
        }, {
            "a": {
                "leaf": true,
                "title": "数据监控",
                "id": 1005,
                "href": "#",
                "data-id": 1005,
                "data-url": "/ssh/druid/index.html",
                "class": "site-demo-active",
            }
        }, {
            "a": {
                "leaf": true,
                "title": "EasyUI",
                "id": 1006,
                "href": "#",
                "data-id": 1006,
                "data-url": "/ssh/easyui/easyui-view",
                "class": "site-demo-active",
            }
        }, {
            "a": {
                "leaf": true,
                "title": "jquery验证",
                "id": 1007,
                "href": "#",
                "data-id": 1007,
                "data-url": "/ssh/jqueryvalidation/validation-view",
                "class": "site-demo-active",
            }
        }, {
            "a": {
                "leaf": true,
                "title": "jquery验证2",
                "id": 1008,
                "href": "#",
                "data-id": 1008,
                "data-url": "/ssh/jqueryvalidation/validation-view2",
                "class": "site-demo-active",
            }
        }, {
            "a": {
                "leaf": false,
                "title": "Layui",
                "id": 1009,
            },
            "dl": {
                "dl-id": "xx",
                "dd": [{
                    "a": {
                        "leaf": true,
                        "title": "Layui学习",
                        "id": 10001,
                        "href": "#",
                        "data-id": 10001,
                        "data-url": "/ssh/layui/layui-view",
                        "class": "site-demo-active",
                    }
                }, {
                    "a": {
                        "leaf": true,
                        "title": "主页展示2",
                        "id": 10002,
                        "href": "#",
                        "data-id": 10002,
                        "data-url": "/ssh/templates/home.html",
                        "class": "site-demo-active",
                    }
                }, {
                    "a": {
                        "leaf": false,
                        "title": "主页展示3",
                        "id": 10003,
                    },
                    "dl": {
                        "dl-id": "xx",
                        "dd": [{
                            "a": {
                                "leaf": true,
                                "title": "主页展示11",
                                "id": 100001,
                                "href": "#",
                                "data-id": 100001,
                                "data-url": "/ssh/templates/home.html",
                                "class": "site-demo-active",
                            }
                        }, {
                            "a": {
                                "leaf": true,
                                "title": "主页展示22",
                                "id": 100002,
                                "href": "#",
                                "data-id": 100002,
                                "data-url": "/ssh/templates/home.html",
                                "class": "site-demo-active",
                            }
                        }, ],
                    }
                }, ],
            }
        }, ],
    }
}, {
    "a": {
        "leaf": false,
        "title": "业务管理",
        "id": 200,
    },
    "dl": {
        "dl-id": "xx",
        "dd": [{
            "a": {
                "leaf": true,
                "title": "主页展示1",
                "id": 2001,
                "href": "#",
                "data-id": 2001,
                "data-url": "/ssh/templates/home.html",
                "class": "site-demo-active",
            }
        }],
    }
}, {
    "a": {
        "leaf": false,
        "title": "报表统计",
        "id": 300,
    },
    "dl": {
        "dl-id": "xx",
        "dd": [{
            "a": {
                "leaf": true,
                "title": "主页展示2",
                "id": 3001,
                "href": "#",
                "data-id": 3001,
                "data-url": "/ssh/templates/home.html",
                "class": "site-demo-active",
            }
        }],
    }
}, ];

后端生成json使用java代码实现:
菜单实体类:

package com.nfl.base.domain;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.utils.BaseDomain;

@Entity
@Table(name = "SSH_MENU")
public class Menu extends BaseDomain {

    private static final long serialVersionUID = -578218727059597787L;

    private String title;

    private String href;

    private Long parentId;

    private Long dataId;

    private String dataUrl;

    private List<Menu> subMenus;

    public void addSubMenus(Menu menu) {
        if (subMenus == null) {
            subMenus = new ArrayList<Menu>();
        }
        subMenus.add(menu);
    }

    @Transient
    public List<Menu> getSubMenus() {
        return subMenus;
    }

    @Column(name = "TITLE")
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    @Column(name = "HREF")
    public String getHref() {
        return href;
    }

    public void setHref(String href) {
        this.href = href;
    }

    @Column(name = "PARENT_ID")
    public Long getParentId() {
        return parentId;
    }

    public void setParentId(Long parentId) {
        this.parentId = parentId;
    }

    @Column(name = "DATA_ID")
    public Long getDataId() {
        return dataId;
    }

    public void setDataId(Long dataId) {
        this.dataId = dataId;
    }

    @Column(name = "DATA_URL")
    public String getDataUrl() {
        return dataUrl;
    }

    public void setDataUrl(String dataUrl) {
        this.dataUrl = dataUrl;
    }
}

上面的BaseDomain是一个生成主键的父类,使用mysql时可以直接把主键定义成自增的形式。

package com.utils;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

import org.hibernate.annotations.GenericGenerator;

@MappedSuperclass
public abstract class BaseDomain implements Serializable {

    private static final long serialVersionUID = 88655228488163320L;

    private Long id;

    @Id
    @GeneratedValue(generator = "MyGenerator")
    @GenericGenerator(name = "MyGenerator", strategy = "com.utils.MyIdGenerator")
    @Column(name = "ID")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

获取所有菜单:

package com.nfl.base.manager;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.nfl.base.domain.Menu;

@Service("menuManager")
public class MenuManager extends AbstractDao<Menu> {

    public Map<Long, Menu> getAllMenu() {
        String hql = "from Menu m order by m.parentId asc,m.id asc";
        List<Menu> menus = this.baseDao.find(null, hql, false);
        Map<Long, Menu> map = new LinkedHashMap<>();
        for (Menu m : menus) {
            map.put(m.getId(), m);
            Menu parentMenu = map.get(m.getParentId());
            if (parentMenu != null) {
                parentMenu.addSubMenus(m);
            }
        }

        return map;
    }
}

生成json数据,放到session:

package com.filter;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import com.nfl.base.domain.Menu;
import com.nfl.base.domain.Person;
import com.nfl.base.manager.MenuManager;
import com.nfl.base.manager.PersonManager;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {

    @Autowired
    private PersonManager personManager;

    @Autowired
    private MenuManager menuManager;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        String username = request.getParameter("username");
        List<Person> personList = personManager.find(null, "from Person p where p.username=?0 order by id asc", false,
                username);
        Person person = personList.get(0);
        HttpSession session = request.getSession();
        session.setAttribute("activeUser", person);
        processMenu(session);
        response.sendRedirect(request.getContextPath() + "/base/person-desktop");
    }

    /**
     * 整理菜单
     */
    private void processMenu(HttpSession session) {
        Map<Long, Menu> allMenu = menuManager.getAllMenu();
        List<Menu> subMenus = allMenu.get(0L).getSubMenus();
        JSONArray jArr = new JSONArray();
        for (Menu subMenu : subMenus) {
            JSONObject jo = new JSONObject();
            if (subMenu.getSubMenus() == null || subMenu.getSubMenus().size() == 0) {
                continue;
            }
            recurrenceMenu(jo, subMenu);
            jArr.add(jo);
        }

        session.setAttribute("allMenus", jArr);
    }

    /**
     * 递归处理菜单,将菜单对象包装成JSONObject对象
     */
    private void recurrenceMenu(JSONObject jo, Menu menu) {
        JSONObject aJo = new JSONObject();
        aJo.put("title", menu.getTitle());
        aJo.put("id", menu.getId());
        // 没有子菜单意味着当前菜单可表示为一片叶子
        if (menu.getSubMenus() == null || menu.getSubMenus().size() == 0) {
            aJo.put("leaf", Boolean.TRUE);

            aJo.put("href", "#");
            aJo.put("data-id", menu.getId());
            aJo.put("data-url", menu.getDataUrl());
            jo.put("a", aJo);
        } else {
            aJo.put("leaf", Boolean.FALSE);

            List<Menu> subMenus = menu.getSubMenus();
            JSONObject dlJo = new JSONObject();
            dlJo.put("dl-id", "xx");
            JSONArray ddjArr = new JSONArray();
            for (Menu mm : subMenus) {
                JSONObject _aJo = new JSONObject();
                recurrenceMenu(_aJo, mm);
                ddjArr.add(_aJo);
            }
            dlJo.put("dd", ddjArr);
            jo.put("a", aJo);
            jo.put("dl", dlJo);
        }
    }
}

请求获取菜单的json数据:

package com.nfl.base.web;

import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import com.nfl.base.domain.Person;
import com.utils.EntityAction;

@Namespace("/base")
@ParentPackage("basePackage")
public class PersonAction extends EntityAction<Person> {

    private static final long serialVersionUID = 8765563996036355208L;

    public void jsonMenu() {
        rendJson(getSessionAttr("allMenus"));
    }
}

菜单表数据
实际上就是一个简单的递归,当前菜单是叶子时代表到底了,不会继续递归。
最后是首页的html:

<!DOCTYPE HTML>
<html>
<head>
<title>(▼へ▼メ)</title>
<meta charset="UTF-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="https://www.layuicdn.com/layui-v2.5.4/css/layui.css">
<style>.layui-tab-content {padding: 0;}</style>
<style>.layui-layout-admin .layui-body {top: 50px;}</style>
</head>
<body class="layui-layout-body">
	<div class="layui-layout layui-layout-admin">
		<div class="layui-header layui-bg-cyan">
		    <div class="layui-logo"><a href=""><i class="layui-icon layui-icon-home" style="color: #1E9FFF;"></i></a></div>
			<ul class="layui-nav layui-layout-left">
				<li class="layui-nav-item"><i title="侧边伸缩" class="layui-icon layui-icon-shrink-right" id="left_open" style="cursor:pointer;"></i></li>
				<li class="layui-nav-item"><a href="">用户<span class="layui-badge">9</span></a></li>
				<li class="layui-nav-item"><a href="">角色<span class="layui-badge-dot"></span></a></li>
				<li class="layui-nav-item"><a href="">权限</a></li>
				<li class="layui-nav-item">
					<a href="javascript:;">其它系统</a>
					<dl class="layui-nav-child layui-anim layui-anim-upbit">
						<dd><a href="">邮件管理</a></dd>
						<dd><a href="">消息管理</a></dd>
						<dd><a href="">授权管理</a></dd>
					</dl>
				</li>
			</ul>
			<ul class="layui-nav layui-layout-right">
				<li class="layui-nav-item">
					<a href="javascript:;">
					    <img src="${contextPath}/images/initpic.jpg" class="layui-nav-img"><b><i>${activeUser.username}</i></b>
					</a>
					<dl class="layui-nav-child">
						<dd><a href="#" id="001" data-url="${contextPath}/systemPages/personal/personalData.jsp" data-id="001" class="">基本资料</a></dd>
						<dd><a href="#" id="002"  data-id="002" class="site-demo-active">修改密码</a></dd>
					</dl>
				</li>
				<li class="layui-nav-item"><a href="${contextPath}/logout">退出</a></li>
			</ul>
		</div>
		<div class="layui-side layui-bg-cyan">
			<div class="layui-side-scroll">
				<ul class="layui-nav layui-nav-tree" lay-shrink="all" id="side-menu"></ul>
			</div>
		</div>
		<div class="layui-body">
			<!-- 内容主体区域 -->
			<div class="layui-tab layui-tab-brief" lay-filter="tabBar" lay-allowClose="true">
				<ul class="layui-tab-title"></ul>
				<ul class="rightmenu" style="display: none;position: absolute;">
					<li data-type="closethis"><a href="javascript:;" class="layui-btn">关闭当前</a></li>
					<li data-type="closeother"><a href="javascript:;" class="layui-btn">关闭其他</a></li>
				</ul>
				<div class="layui-tab-content"></div>
			</div>
		</div>
		<div class="layui-footer">页底区域</div>
	</div>
	<script src="https://cdn.bootcss.com/jquery/1.7.2/jquery.min.js"></script>
	<script src="https://www.layuicdn.com/layui-v2.5.4/layui.js"></script>
	<script src="${contextPath}/js/tabs.js"></script>
	<script src="${contextPath}/js/dynamicMenu.js"></script>
	<script src="${contextPath}/js/desktop.js"></script>
</body>
</html>

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值