layui 无限级别菜单

表结构

CREATE TABLE `menu` (
  `menu_id` int(11) NOT NULL AUTO_INCREMENT,
  `pid` int(11) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `icon` varchar(20) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL,
  `sort` int(11) NULL DEFAULT NULL,
  `remark` varchar(255) DEFAULT NULL,
  `state` varchar(10) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`menu_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

造些数据

INSERT INTO `menu` VALUES (1, NULL, '系统管理', '', NULL, 1, NULL, 'A', now(), now());
INSERT INTO `menu` VALUES (2, 1, '菜单管理', '', NULL, 1, NULL, 'A', now(), now());
INSERT INTO `menu` VALUES (3, 2, '新增菜单', '', NULL, NULL, NULL, 'A', now(), now());
INSERT INTO `menu` VALUES (4, NULL, '账户管理', '', NULL, 2, NULL, 'A', now(), now());
INSERT INTO `menu` VALUES (5, 1, '权限管理', '', NULL, 2, NULL, 'A', now(), now());
INSERT INTO `menu` VALUES (6, 4, '账户列表', '', NULL, NULL, NULL, 'A', now(), now());
INSERT INTO `menu` VALUES (7, 3, '新菜单', '', NULL, NULL, NULL, 'A', now(), now());
INSERT INTO `menu` VALUES (8, 7, '新菜单1', NULL, NULL, NULL, NULL, 'A', now(), now());

后台接口

Action

@RestController
@RequestMapping(value = "menu")
@Slf4j
public class MenuAction {

    @Autowired
    private MenuService menuService;

    @RequestMapping(value = "getMenu", method = RequestMethod.GET)
    public Result getMenuJson() {
        Result result = new MapResult();
        try {
            result = menuService.getMenuJson(null);
        }catch (Exception e){
            log.error("MenuAction.getMenu:"+e.getMessage());
        }
        return result;
    }
}

serviceImpl

    @Override
    public Result getMenuJson(Integer userId) {
        Result result = new MapResult();
        try {
            JSONObject menuJson = new JSONObject();
            getAllChildrenMenuByPid(menuJson);
            result.defaultSuccess();
            result.setData("menuJson", menuJson);
        } catch (Exception e) {
            Logger.exception(e.getMessage(), e);
            result.setMessage(e.getMessage());
        }


        return result;
    }
	/**
	 * 递归查询 节点下子节点
	 */
    private void getAllChildrenMenuByPid(JSONObject pJson) {

        Integer pid = pJson.getInteger("menuId");

        List<Menu> childrenMenus = menuMapper.getMenuByPid(pid);

        if (childrenMenus==null||childrenMenus.isEmpty()) return;

        JSONArray children = new JSONArray();
        for (Menu child : childrenMenus) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("pid",child.getPid());
            jsonObject.put("name",child.getName());
            jsonObject.put("menuId",child.getMenuId());
            jsonObject.put("icon",child.getIcon());
            jsonObject.put("url",child.getUrl());
            children.add(jsonObject);
            //递归查询
            getAllChildrenMenuByPid(jsonObject);
        }
        pJson.put("children",children);
    }

dao

List<Menu> getMenuByPid(@Param("pid") Integer pid);

Mapper.xml

	<!-- 根据父级查询 -->
    <select id="getMenuByPid" resultMap="MenuMap">
        select * from menu 
        where
        state!='X'
        <if test="pid==null or pid=='' ">
            and pid is null or pid =''
        </if>
        <if test="pid!=null and pid!='' ">
            and pid = #{pid}
        </if>
        order by `sort` desc
    </select>

pojo

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;


/**
 * @author 
 *
 */

@Data
@EqualsAndHashCode
@ToString
public class Menu implements Pojo {

	private static final long serialVersionUID = -1L;
	//columns START
	/** menuId */
	private java.lang.Integer menuId;
	/** pid */
	private java.lang.Integer pid;
	/** name */
	private java.lang.String name;
	/** icon */
	private java.lang.String icon;
	/** sort */
	private java.lang.Integer sort;
	/** url */
	private java.lang.String url;
	/** remark */
	private java.lang.String remark;
	/** state */
	private java.lang.String state;
	/** createTime */
	private java.util.Date createTime;
	/** updateTime */
	private java.util.Date updateTime;
	//columns END
}

前端代码
html

<!-- 左侧菜单开始 -->
<div class="left-nav">
    <div id="side-nav">
        <ul id="nav">

        </ul>
    </div>
</div>
<!-- 左侧菜单结束 -->

js

    $(function () {
        initMenu()
    });
	/**
     * 加载菜单
     */
    function initMenu() {
        $.ajax({
            url: '/menu/getMenu',
            dataType: 'json',
            success: function (result) {
                var menuJson = result.datas.menuJson.children;
                if (menuJson) {
                    var $html = $('#nav');
                    getMenuHtml($html, menuJson, 0)
                }

                console.log(menuJson);
            }
        });
    }
	/**
     * 获取菜单html
     * @param $html 需要填充的dom
     * @param menu_list 数据
     * @param num 菜单级别
     */
    function getMenuHtml($html, menu_list, num) {
        num++;
        for (var i in menu_list) {
            var menu = menu_list[i];
            var pid = menu['pid'];
            var menuId = menu['menuId'];
            var name = menu['name'];
            var icon = menu['icon'];
            var url = menu['url'];
            var children = menu['children'];
            if (pid === null || pid === '') {
                var html_new_ =
                    '<li  id="' + menuId + '">' +
                    '<a style="padding-left: '+10*num+'px;" href="javascript:;">' +
                    '<i class="layui-icon left-nav-li" lay-tips="' + name + '">' + (icon ? icon : '&#xe723;') + '</i>' +
                    '<cite>' + name + '</cite>' +
                    '<i class="iconfont nav_right">&#xe697;</i></a>' +
                    '<ul class="sub-menu" id="menu_ul_' + menuId + '">' +
                    '</ul>' +
                    '</li>';
                $html.append(html_new_);
            } else {
                var html;
                if (children && children.length > 0) {
                    html =
                        '<li id="' + menuId + '">' +
                        '<a style="padding-left: '+10*num+'px;" href="javascript:;">' +
                        '<i class="layui-icon left-nav-li" lay-tips="' + name + '">' + (icon ? icon : '&#xe723;') + '</i>' +
                        '<cite>' + name + '</cite>' +
                        '<i class="iconfont nav_right">&#xe697;</i></a>' +
                        '<ul class="sub-menu" id="menu_ul_' + menuId + '">' +
                        '</ul>' +
                        '</li>';
                    $("#menu_ul_" + pid).append(html);
                } else {
                    html = ' <li>' +
                        ' <a  style="padding-left: '+10*num+'px;" οnclick="xadmin.add_tab(\'' + name + '\',\'' + url + '\')">' +
                        '  <i class="layui-icon">'+ (icon ? icon : '&#xe602;') + '</i>' +
                        '  <cite>' + name + '</cite></a>' +
                        '<ul id="menu_ul_' + menuId + '">' +
                        '</ul>' +
                        ' </li>';
                    $("#menu_ul_" + pid).append(html);
                }

            }
            if (children && children.length > 0) {
                getMenuHtml($html, children,num);
            }
        }
    }

效果
在这里插入图片描述
总结
造了五级数据,速度有点慢,应该能优化
异步菜单会后展示1s,同步整个页面加载慢一点
在这里插入图片描述
测试几次 基本在800ms 到 1s 之间,有缓存在80~150ms

方案一:
减少查询次数,一次查出数据,然后在内存构造数据结构
方案二:
改变数据结构,能否用有序集合解决。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值