其中后端代碼不包含權限控制,同時支持二級(無子菜單) 和 三級菜單(無子菜單)。
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"> ${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:;"> ${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"> ${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語句省略,這個比較簡單,只用到了普通查詢和幾個子查詢。。。。