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

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

 <div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul class="layui-nav layui-nav-tree" id="chuizhi" lay-filter="test"></ul>
</div>
</div> <div class="layui-body">
<!-- 内容主体区域 -->
<iframe name="iframe" src="/test/welcome" width="100%" height="100%"
frameborder="no" border="0" scrolling="auto"></iframe>
</div> <div class="layui-footer">
<!-- 底部固定区域 -->
© myzy.cn -
</div> <script> function isArrayFn(value){//用于判断对象是否为数组.
if (typeof Array.isArray === "function") {
return Array.isArray(value);
}else{
return Object.prototype.toString.call(value) === "[object Array]";
}
}
//JavaScript代码区域
layui.use(['form', 'layedit','element', 'layer','laydate','table'], function(){
var table = layui.table
,element = layui.element
,form = layui.form
,layer = layui.layer
,layedit = layui.layedit
,laydate = layui.laydate
,$ = layui.jquery;
37 //动态渲染树形菜单
$.post("/todo/treeData", function (data){//请求后端返回对应json
var menu1 = [];//所有一级菜单名称数组
for (var key in data) {
menu1.push(key);
}
var len = menu1.length;
for(var i=0;i<len;i++){
$("#chuizhi").append(`<li class="layui-nav-item"><a href="javascript:;">${menu1[i]}</a>
<dl class="layui-nav-child ${menu1[i]}">
</dl></li>`);//一级菜单(有子菜单)
let ss = data[menu1[i]];
if(isArrayFn(ss)){
for(let j=0;j<ss.length;j++){
$("."+menu1[i]).append(`<dd class="twoMenu"><a href="${ss[j].url}" target="iframe">&nbsp;&nbsp;${ss[j].name}</a></dd>`);//只到(没有子菜单)二级菜单
}
}else{
let arr = [];
for(var key in ss){
arr = ss[key];
$("."+menu1[i]).append(`<li class="layui-nav-item twoMenu"><a href="javascript:;">&nbsp;${key}</a>
<dl class="layui-nav-child ${key}">
</dl></li>`);//二级菜单(有子菜单)
for(let j=0;j<arr.length;j++){
$("."+key).append(`<dd><a href="${arr[j].url}" target="iframe">&nbsp;&nbsp;${arr[j].name}</a></dd>`);//只到(没有子菜单)三级菜单
}
}
}
}
element.render();//element.init();//全部更新,用于动态渲染之后的挂载 (2)
/**用于菜单显示效果:点击其他菜单,原来打开的菜单自动关闭*/
$(".twoMenu,#chuizhi>li").on("click",function () {
if(!$(this).hasClass("layui-nav-itemed")){
$(this).removeClass("layui-nav-itemed");
if($(this).children().children().hasClass("layui-nav-itemed")){
$(this).children().children().removeClass("layui-nav-itemed");
}
}else if($(this).hasClass("layui-nav-itemed")){
$(this).addClass("layui-nav-itemed");
$(this).siblings().removeClass("layui-nav-itemed");
if(!$(this).children().children().hasClass("layui-nav-itemed")){
$(this).children().children().removeClass("layui-nav-itemed");
}
}
}) })
});
</script>

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

 @Override//其中menu_duidMapper为装载的dao层接口
public Map<String, Object> queryJsonMenus() {
Map<String, Object> mapR = new LinkedHashMap<String, Object>();
//Map<String,Map<String,List<Map<String,String>>>> mapSan = new LinkedHashMap<>();//前端三级菜单json在后端表现形式
//Map<String,List<Map<String,String>>> mapTwo = new LinkedHashMap<>();//前端二级菜单json在后端表现形式
List<String> oneLevelMenuId = menu_duidMapper.selectGoodsMenuIdOneJ();//一级菜单id
List<String> TwoLevelPId = menu_duidMapper.selectGoodsParentIdTwoJ(); //二级菜单fuid
List<String> grandIdThreeJ = menu_duidMapper.selectGoodsGrandIdThreeJ();//三级菜单祖父id
String oneName = null;
String twoName = null;
List<Map<String,String>> msp = null;
List<String> threePid = null;
for(String oneMid : oneLevelMenuId){
Map<String,List<Map<String,String>>> mapTwo = new LinkedHashMap<>();//这里不可以使用单例,所以只能生命在for循环内部
for(String erPid : TwoLevelPId){
if(oneMid.equals(erPid)){
oneName = menu_duidMapper.selectGoodsTypeByMenuId(oneMid);//根据一级菜单menuid查询对应名称
msp = menu_duidMapper.selectGoodsMapByPid(erPid);//根据二级菜单父id查找对应二级map
mapR.put(oneName,msp);//填充一级菜单对应的二级菜单(无子菜单)
}else{
continue;
}
}
for(String sanGpid : grandIdThreeJ){
if(oneMid.equals(sanGpid)){
oneName = menu_duidMapper.selectGoodsTypeByMenuId(oneMid);//
threePid = menu_duidMapper.selectGoodsParentIdThreeJByGrandId(sanGpid);//根据祖父id查询父id并去重
for(String tpid : threePid){
msp = menu_duidMapper.selectGoodsMapByPidAndGpid(tpid,sanGpid);//根据祖父id和父id查询对应map
twoName = menu_duidMapper.selectGoodsTypeByMenuId(tpid);//根据三级菜单父id查询对应二级菜单
//System.out.println(twoName);
mapTwo.put(twoName,msp);//填充二级菜单(有子菜单)和对应三级菜单(物资菜单)
}
mapR.put(oneName,mapTwo);//填充一级菜单所对应的二(有子菜单)三(无子菜单)级菜单
}else{
continue;
}
}
}
return mapR;
}

3.数据库表结构

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

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

 {
"新闻资讯":{
"企业新闻":[
{
"menuID":"010101",
"name":"xxx",
"url":"/test/petroleum010101"
},
{
"menuID":"010102",
"name":"xxx",
"url":"/test/mAsphalt010102"
}
],
"行业新闻":[
{
"menuID":"010201",
"name":"xxx",
"url":"/test/petroleum010201"
},
{
"menuID":"010202",
"name":"xxx",
"url":"/test/mAsphalt010202"
}
]
},
"行业报告":{
"日报":[
{
"menuID":"020101",
"name":"xxx",
"url":"/test/petroleum020101"
},
{
"menuID":"020102",
"name":"xxx",
"url":"/test/mAsphalt020102"
}
],
"周报":[
{
"menuID":"020201",
"name":"xxx",
"url":"/test/petroleum020201"
},
{
"menuID":"020202",
"name":"xxxx",
"url":"/test/mAsphalt020202"
}
],
"月报":[
{
"menuID":"",
"name":"xxx",
"url":"/test/petroleum020301"
},
{
"menuID":"",
"name":"xxx",
"url":"/test/mAsphalt020302"
}
],
"年报":[
{
"menuID":"",
"name":"xxx",
"url":"/test/petroleum020401"
},
{
"menuID":"",
"name":"xxx",
"url":"/test/mAsphalt020402"
}
]
},
"政策法规":[
{
"menuID":"",
"name":"xxx",
"url":"/test/petroleum0301"
},
{
"menuID":"",
"name":"xxx",
"url":"/test/mAsphalt0302"
}
]
}

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

动态渲染左侧菜单栏 :menu tree 动态渲染的更多相关文章

  1. vue 动态渲染数据很慢或不渲染

    vue 动态渲染数据很慢或不渲染 原因是因为vue检测速度很慢,因为多层循环了,在VUE 2.x的时候还能渲染出来,1.x的时候压根渲染不出来.解决方式:在动态改变数据的方法,第一行加上 this.$ ...

  2. Android动态修改ToolBar的Menu菜单

    Android动态修改ToolBar的Menu菜单 效果图 实现 实现很简单,就是一个具有3个Action的Menu,在我们滑动到不同状态的时候,把对应的Action隐藏了. 开始上货 Menu Me ...

  3. 细说后端模板渲染、客户端渲染、node 中间层、服务器端渲染(ssr)

    细说后端模板渲染.客户端渲染.node 中间层.服务器端渲染(ssr) 前端与后端渲染方式的发展大致经历了这样几个阶段:后端模板渲染.客户端渲染.node 中间层.服务器端渲染(ssr). 1. 后端 ...

  4. [转贴]Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程

    看了opengles有一段时间了,算是了解了一下下.然后,就在基本要决定还是回归cocos2dx 3.2的,看了这篇好文章,欣喜转之~ 推荐看原帖: Cocos2d-x3.2与OpenGL渲染总结(一 ...

  5. 某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException异常的解决方法

    在某APK中,通过如下方法动态注册了一个BroadcastReceiver,代码参考如下: @Override protected void onAttachedToWindow() { super. ...

  6. WebStorm设置左侧菜单栏背景和字体设置

    WebStorm左侧菜单栏 webstorm是一款前端IDE利器,个人感觉黑色的背景比较炫酷,刚开始从网上下载的主题只能修改编辑窗口的背景色,经过查询资料终于把左边菜单栏的背景色也修改了. 第一步:点 ...

  7. 模仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(上)

      我们大部分人都发过动态,想必都知道发动态.回复评论.删除动态的整个过程,那么作为初学者,要模仿这些功能有点复杂的,最起码表的关系得弄清楚~~ 先把思路理一下: (1)用户登录,用session读取 ...

  8. PHP系统左侧菜单栏的管理与实现

    在日常的开发工作中,面对后台的日益增长的业务,以及后期业务的迭代开发,通常会选择添加菜单栏的形式来扩充业务功能,同样日益增长的后台菜单选项也为我们后期的维护,产生了一定的困难性.为此我总结出自己关于左 ...

  9. 代理模式(静态代理、JDK动态代理原理分析、CGLIB动态代理)

    代理模式 代理模式是设计模式之一,为一个对象提供一个替身或者占位符以控制对这个对象的访问,它给目标对象提供一个代理对象,由代理对象控制对目标对象的访问. 那么为什么要使用代理模式呢? 1.隔离,客户端 ...

随机推荐

  1. 搭建Portainer可视化界面(转)

    转载地址:https://blog.csdn.net/u011781521/article/details/80469804 一.什么是Portainer? Portainer是Docker的图形化管 ...

  2. /bin/sh^M:解释器错误:没有那个文件或目录

    在win下编辑的时候,换行结尾是\n\r , 而在linux下 是\n,所以才会有 多出来的\rsed -i 's/\r$//' configure 删除configure脚本中的\r

  3. [整理] linux ubuntu 服务器键盘设置错误 完美解决

    根据 原文来源:https://blog.csdn.net/mingjie1212/article/details/48525095 进行修改. 使用命令 dpkg-reconfigure keybo ...

  4. All LeetCode Questions List 题目汇总

    All LeetCode Questions List(Part of Answers, still updating) 题目汇总及部分答案(持续更新中) Leetcode problems clas ...

  5. OSI七层与TCP/IP四层(小结)

    OSI 七层模型 我们一般使用的网络数据传输由下而上共有七层,分别为物理层.数据链路层.网络层.传输层.会话层.表示层.应用层,也被依次称为 OSI 第一层.第二层.⋯⋯. 第七层. 各层功能简介 1 ...

  6. 1-4dockerfile基本使用

    1.创建一个文件夹 mkdir mynginx cd mynginx touch Dockerfile [root@VM_0_10_centos mynginx]# cat Dockerfile FR ...

  7. CentOS 7.5 使用 yum 安装 Kubernetes 集群(二)

    一.安装方式介绍 1.yum 安装 目前CentOS官方已经把Kubernetes源放入到自己的默认 extras 仓库里面,使用 yum 安装,好处是简单,坏处也很明显,需要官方更新 yum 源才能 ...

  8. (CSDN迁移)JAVA多线程实现-单线程化线程池newSingleThreadExecutor

    JAVA通过Executors提供了四种线程池,单线程化线程池(newSingleThreadExecutor).可控最大并发数线程池(newFixedThreadPool).可回收缓存线程池(new ...

  9. Google Colab——零成本玩转深度学习

    前言 最近在学深度学习HyperLPR项目时,由于一直没有比较合适的设备训练深度学习的模型,所以在网上想找到提供模型训练,经过一段时间的搜索,最终发现了一个谷歌的产品--Google Colabora ...

  10. 单选 textarea 赋初值

    自闭合标签赋初值用$().val(),比如:<input type="text" name="text" value="123"> ...