动态渲染左侧菜单栏 :menu tree 动态渲染

其中后端代码不包含权限控制,同时支持二级(无子菜单) 和 三级菜单(无子菜单)。

1、layui前端代码:(其他前端框架实现方法通用,不过需要修改js中append对应标签元素即可)

 1 <div class="layui-side layui-bg-black">
 2         <div class="layui-side-scroll">
 3             <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
 4             <ul class="layui-nav layui-nav-tree" id="chuizhi"  lay-filter="test"></ul>
 5         </div>
 6     </div>
 7 
 8     <div class="layui-body">
 9         <!-- 内容主体区域 -->
10         <iframe name="iframe" src="/test/welcome" width="100%" height="100%"
11                 frameborder="no" border="0" scrolling="auto"></iframe>
12     </div>
13 
14     <div class="layui-footer">
15         <!-- 底部固定区域 -->
16         © myzy.cn - 
17     </div>
18 
19 <script>
20 
21     function isArrayFn(value){//用于判断对象是否为数组.
22         if (typeof Array.isArray === "function") {
23             return Array.isArray(value);
24         }else{
25             return Object.prototype.toString.call(value) === "[object Array]";
26         }
27     }
28     //JavaScript代码区域
29     layui.use(['form', 'layedit','element', 'layer','laydate','table'], function(){
30         var table = layui.table
31             ,element = layui.element
32             ,form = layui.form
33             ,layer = layui.layer
34             ,layedit = layui.layedit
35             ,laydate = layui.laydate
36             ,$ = layui.jquery;
37

38 39 //动态渲染树形菜单 40 $.post("/todo/treeData", function (data){//请求后端返回对应json 41 var menu1 = [];//所有一级菜单名称数组 42 for (var key in data) { 43 menu1.push(key); 44 } 45 var len = menu1.length; 46 for(var i=0;i<len;i++){ 47 $("#chuizhi").append(`<li class="layui-nav-item"><a href="javascript:;">${menu1[i]}</a> 48 <dl class="layui-nav-child ${menu1[i]}"> 49 </dl></li>`);//一级菜单(有子菜单) 50 let ss = data[menu1[i]]; 51 if(isArrayFn(ss)){ 52 for(let j=0;j<ss.length;j++){ 53 $("."+menu1[i]).append(`<dd class="twoMenu"><a href="${ss[j].url}" target="iframe">&nbsp;&nbsp;${ss[j].name}</a></dd>`);//只到(没有子菜单)二级菜单 54 } 55 }else{ 56 let arr = []; 57 for(var key in ss){ 58 arr = ss[key]; 59 $("."+menu1[i]).append(`<li class="layui-nav-item twoMenu"><a href="javascript:;">&nbsp;${key}</a> 60 <dl class="layui-nav-child ${key}"> 61 </dl></li>`);//二级菜单(有子菜单) 62 for(let j=0;j<arr.length;j++){ 63 $("."+key).append(`<dd><a href="${arr[j].url}" target="iframe">&nbsp;&nbsp;${arr[j].name}</a></dd>`);//只到(没有子菜单)三级菜单 64 } 65 } 66 } 67 } 68 element.render();//element.init();//全部更新,用于动态渲染之后的挂载 (2) 69 /**用于菜单显示效果:点击其他菜单,原来打开的菜单自动关闭*/ 70 $(".twoMenu,#chuizhi>li").on("click",function () { 71 if(!$(this).hasClass("layui-nav-itemed")){ 72 $(this).removeClass("layui-nav-itemed"); 73 if($(this).children().children().hasClass("layui-nav-itemed")){ 74 $(this).children().children().removeClass("layui-nav-itemed"); 75 } 76 }else if($(this).hasClass("layui-nav-itemed")){ 77 $(this).addClass("layui-nav-itemed"); 78 $(this).siblings().removeClass("layui-nav-itemed"); 79 if(!$(this).children().children().hasClass("layui-nav-itemed")){ 80 $(this).children().children().removeClass("layui-nav-itemed"); 81 } 82 } 83 }) 84 85 }) 86 }); 87 </script>

2.java后端代码:用于返回给前端 菜单(json) 数据

 1 @Override//其中menu_duidMapper为装载的dao层接口
 2     public Map<String, Object> queryJsonMenus() {
 3         Map<String, Object> mapR = new LinkedHashMap<String, Object>();
 4         //Map<String,Map<String,List<Map<String,String>>>> mapSan = new LinkedHashMap<>();//前端三级菜单json在后端表现形式
 5         //Map<String,List<Map<String,String>>> mapTwo = new LinkedHashMap<>();//前端二级菜单json在后端表现形式
 6         List<String> oneLevelMenuId = menu_duidMapper.selectGoodsMenuIdOneJ();//一级菜单id
 7         List<String> TwoLevelPId = menu_duidMapper.selectGoodsParentIdTwoJ(); //二级菜单fuid
 8         List<String> grandIdThreeJ = menu_duidMapper.selectGoodsGrandIdThreeJ();//三级菜单祖父id
 9         String oneName = null;
10         String twoName = null;
11         List<Map<String,String>> msp = null;
12         List<String> threePid = null;
13         for(String oneMid : oneLevelMenuId){
14             Map<String,List<Map<String,String>>> mapTwo = new LinkedHashMap<>();//这里不可以使用单例,所以只能生命在for循环内部
15             for(String erPid : TwoLevelPId){
16                 if(oneMid.equals(erPid)){
17                     oneName = menu_duidMapper.selectGoodsTypeByMenuId(oneMid);//根据一级菜单menuid查询对应名称
18                     msp = menu_duidMapper.selectGoodsMapByPid(erPid);//根据二级菜单父id查找对应二级map
19                     mapR.put(oneName,msp);//填充一级菜单对应的二级菜单(无子菜单)
20                 }else{
21                     continue;
22                 }
23             }
24             for(String sanGpid : grandIdThreeJ){
25                 if(oneMid.equals(sanGpid)){
26                     oneName = menu_duidMapper.selectGoodsTypeByMenuId(oneMid);//
27                     threePid = menu_duidMapper.selectGoodsParentIdThreeJByGrandId(sanGpid);//根据祖父id查询父id并去重
28                     for(String tpid : threePid){
29                         msp = menu_duidMapper.selectGoodsMapByPidAndGpid(tpid,sanGpid);//根据祖父id和父id查询对应map
30                         twoName = menu_duidMapper.selectGoodsTypeByMenuId(tpid);//根据三级菜单父id查询对应二级菜单
31                         //System.out.println(twoName);
32                         mapTwo.put(twoName,msp);//填充二级菜单(有子菜单)和对应三级菜单(物资菜单)
33                     }
34                     mapR.put(oneName,mapTwo);//填充一级菜单所对应的二(有子菜单)三(无子菜单)级菜单
35                 }else{
36                     continue;
37                 }
38             }
39         }
40         return mapR;
41     }

3.数据库表结构

 1 DROP TABLE IF EXISTS `menu_duid`;
 2 CREATE TABLE `menu_duid`  (
 3   `id` int(11) NOT NULL AUTO_INCREMENT,
 4   `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
 5   `menu_id` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单id',
 6   `parent_id` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '菜单父id',
 7   `grand_pid` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '菜单爷爷id',
 8   `url` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单路径',
 9   `romaker` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
10   PRIMARY KEY (`id`) USING BTREE
11 ) ENGINE = InnoDB AUTO_INCREMENT = 96 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

4.ajax返回的json数据格式为

 1 {
 2     "新闻资讯":{
 3         "企业新闻":[
 4             {
 5                 "menuID":"010101",
 6                 "name":"xxx",
 7                 "url":"/test/petroleum010101"
 8             },
 9             {
10                 "menuID":"010102",
11                 "name":"xxx",
12                 "url":"/test/mAsphalt010102"
13             }
14         ],
15         "行业新闻":[
16             {
17                 "menuID":"010201",
18                 "name":"xxx",
19                 "url":"/test/petroleum010201"
20             },
21             {
22                 "menuID":"010202",
23                 "name":"xxx",
24                 "url":"/test/mAsphalt010202"
25             }
26         ]
27     },
28     "行业报告":{
29         "日报":[
30             {
31                 "menuID":"020101",
32                 "name":"xxx",
33                 "url":"/test/petroleum020101"
34             },
35             {
36                 "menuID":"020102",
37                 "name":"xxx",
38                 "url":"/test/mAsphalt020102"
39             }
40         ],
41         "周报":[
42             {
43                 "menuID":"020201",
44                 "name":"xxx",
45                 "url":"/test/petroleum020201"
46             },
47             {
48                 "menuID":"020202",
49                 "name":"xxxx",
50                 "url":"/test/mAsphalt020202"
51             }
52         ],
53         "月报":[
54             {
55                 "menuID":"",
56                 "name":"xxx",
57                 "url":"/test/petroleum020301"
58             },
59             {
60                 "menuID":"",
61                 "name":"xxx",
62                 "url":"/test/mAsphalt020302"
63             }
64         ],
65         "年报":[
66             {
67                 "menuID":"",
68                 "name":"xxx",
69                 "url":"/test/petroleum020401"
70             },
71             {
72                 "menuID":"",
73                 "name":"xxx",
74                 "url":"/test/mAsphalt020402"
75             }
76         ]
77     },
78     "政策法规":[
79         {
80             "menuID":"",
81             "name":"xxx",
82             "url":"/test/petroleum0301"
83         },
84         {
85             "menuID":"",
86             "name":"xxx",
87             "url":"/test/mAsphalt0302"
88         }
89     ]
90 }

5.对应查询的sql语句省略,这个比较简单,只用到了普通查询和几个子查询。。。。

原文地址:https://www.cnblogs.com/yzyBalance/p/11641964.html