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

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. 【Layui】侧边菜单导航禁用折叠、去除箭头样式

    官方提供的样式代码: <ul class="layui-nav layui-nav-tree" lay-filter="test"> <!-- ...

  2. Springboot配置连接两个数据库

    背景: 项目中需要从两个不同的数据库查询数据,之前实现方法是:springboot配置连接一个数据源,另一个使用jdbc代码连接. 为了改进,现在使用SpringBoot配置连接两个数据源 实现效果: ...

  3. PAT-2019年冬季考试-甲级 7-2 Block Reversing (25分) (链表转置)

    7-2 Block Reversing (25分)   Given a singly linked list L. Let us consider every K nodes as a block ( ...

  4. BeetlConfiguration扩展配置

    beetl拓展配置类,绑定一些工具类,方便在模板中直接调用 BeetlConfiguration.java public class BeetlConfiguration extends BeetlG ...

  5. LeetCode_459. Repeated Substring Pattern

    459. Repeated Substring Pattern Easy Given a non-empty string check if it can be constructed by taki ...

  6. 大数据 -- Cloudera Manager(简称CM)+CDH构建大数据平台

    一.Cloudera Manager介绍 Cloudera Manager(简称CM)是Cloudera公司开发的一款大数据集群安装部署利器,这款利器具有集群自动化安装.中心化管理.集群监控.报警等功 ...

  7. windows 系统下安装docker

    一.介绍 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间 ...

  8. mybatis一级二级缓存

    一级缓存分析 不需要任何配置 ,mybatis本身带有 一级缓存是SqlSession范围的缓存,当调用SqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓 ...

  9. 利用MySQL存储过程批量插入100W条测试数据

    DROP PROCEDURE IF EXISTS insert_batch; CREATE PROCEDURE insert_batch() BEGIN ; loopname:LOOP '); ; T ...

  10. 文件和异常的练习3——python编程从入门到实践

    10-10 常见单词:访问项目Gutenberg(http://gutenberg.org/),并找一些你想分析的图书.下载这些作品的文本文件或将浏览器中的原始文本复制到文本文件中. 可以使用coun ...