LayUI 实现二级导航栏

news2024/11/24 15:23:24

目录

实现步骤:

1. 分析数据库

2. 构建数据源

2.1 编写实体类

2.2 编写节点实体类

2.3 构建BuildTree节点结构方法类

2.4 编写dao类

2.5 编写数据Acntion控制类

3. 前台准备

3.1 配置mvc.xml文件

3.2 页面编写

3.3 运行效果


实现步骤:

1. 分析数据库

        如图所示,聪明的你可能发现了!有的数据的属性pid有多个相同的值并且对应了id的值。由此发现它们是有某种关系的,我也不打哑谜了,数据库设计呢,就是把所有一级菜单(最大的菜单)的某一个值设置为一致,这样后来我们只要查询这个值就可以获取所有一级菜单。

这些都是父级内容

 pid10就是id10下的子菜单!

pid:“所以我们现在是什么关系?”

id:“I'm your father🫰”

 

2. 构建数据源

2.1 编写实体类

package com.ycxw.entity;

/**
 * 会议系统实体类
 * 
 * @author 云村小威
 *
 * @2023年7月11日 下午9:41:18
 */
public class Permission {
	private long id;
	private String name;
	private String description;
	private String url;
	private long pid;
	private int ismenu;
	private long displayno;

	public Permission() {
		// TODO Auto-generated constructor stub
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public long getPid() {
		return pid;
	}

	public void setPid(long pid) {
		this.pid = pid;
	}

	public int getIsmenu() {
		return ismenu;
	}

	public void setIsmenu(int ismenu) {
		this.ismenu = ismenu;
	}

	public long getDisplayno() {
		return displayno;
	}

	public void setDisplayno(long displayno) {
		this.displayno = displayno;
	}

	public Permission(long id, String name, String description, String url, long pid, int ismenu, long displayno) {
		super();
		this.id = id;
		this.name = name;
		this.description = description;
		this.url = url;
		this.pid = pid;
		this.ismenu = ismenu;
		this.displayno = displayno;
	}

	@Override
	public String toString() {
		return "Permission [id=" + id + ", name=" + name + ", description=" + description + ", url=" + url + ", pid="
				+ pid + ", ismenu=" + ismenu + ", displayno=" + displayno + "]";
	}

}

 

2.2 编写节点实体类

package com.zking.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 
 * @author 云村小威
 *
 * @2023年7月12日 上午11:13:05
 */
public class TreeVo<T> {
	/**
	 * 节点ID
	 */
	private String id;
	/**
	 * 显示节点文本
	 */
	private String text;
	/**
	 * 节点状态,open closed
	 */
	private Map<String, Object> state;
	/**
	 * 节点是否被选中 true false
	 */
	private boolean checked = false;
	/**
	 * 节点属性
	 */
	private Map<String, Object> attributes;

	/**
	 * 节点的子节点
	 */
	private List<TreeVo<T>> children = new ArrayList<TreeVo<T>>();

	/**
	 * 父ID
	 */
	private String parentId;
	/**
	 * 是否有父节点
	 */
	private boolean hasParent = false;
	/**
	 * 是否有子节点
	 */
	private boolean hasChildren = false;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public Map<String, Object> getState() {
		return state;
	}

	public void setState(Map<String, Object> state) {
		this.state = state;
	}

	public boolean isChecked() {
		return checked;
	}

	public void setChecked(boolean checked) {
		this.checked = checked;
	}

	public Map<String, Object> getAttributes() {
		return attributes;
	}

	public void setAttributes(Map<String, Object> attributes) {
		this.attributes = attributes;
	}

	public List<TreeVo<T>> getChildren() {
		return children;
	}

	public void setChildren(List<TreeVo<T>> children) {
		this.children = children;
	}

	public boolean isHasParent() {
		return hasParent;
	}

	public void setHasParent(boolean isParent) {
		this.hasParent = isParent;
	}

	public boolean isHasChildren() {
		return hasChildren;
	}

	public void setChildren(boolean isChildren) {
		this.hasChildren = isChildren;
	}

	public String getParentId() {
		return parentId;
	}

	public void setParentId(String parentId) {
		this.parentId = parentId;
	}

	public TreeVo(String id, String text, Map<String, Object> state, boolean checked, Map<String, Object> attributes,
                  List<TreeVo<T>> children, boolean isParent, boolean isChildren, String parentID) {
		super();
		this.id = id;
		this.text = text;
		this.state = state;
		this.checked = checked;
		this.attributes = attributes;
		this.children = children;
		this.hasParent = isParent;
		this.hasChildren = isChildren;
		this.parentId = parentID;
	}

	public TreeVo() {
		super();
	}

}

2.3 构建BuildTree节点结构方法类

package com.zking.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 云村小威
 *
 * @2023年7月12日 上午11:15:30
 */
public class BuildTree {

	
	/**
	 * 指定idparam为顶级节点
	 * 
	 * @param nodes
	 * @param idParam
	 * @param <T>
	 * @return
	 */
	public static <T> List<TreeVo<T>> buildList(List<TreeVo<T>> nodes, String idParam) {
		if (nodes == null) {
			return null;
		}
		List<TreeVo<T>> topNodes = new ArrayList<TreeVo<T>>();
		//遍历传过来的节点数据
		for (TreeVo<T> children : nodes) {
			//获取父级id
			String pid = children.getParentId();
			//如果跟传过来的id相同
			if (pid == null || idParam.equals(pid)) {
				//就判定这个父级菜单
				topNodes.add(children);
				//继续执行下操作
				continue;
			}
			
			for (TreeVo<T> parent : nodes) {
				//获取id
				String id = parent.getId();
				//判断父级id是否等于pid
				if (id != null && id.equals(pid)) {
					//等于就判定它是谁的儿子
					parent.getChildren().add(children);
					//设置是否有父节点和子节点
					children.setHasParent(true);
					parent.setChildren(true);

					continue;
				}
			}

		}
		return topNodes;
	}

}

2.4 编写dao类

后台方法构建好后,只需将数据源进行Json解析后,进行后台获取输出到页面即可:

package com.ycxw.dao;

import java.util.ArrayList;
import java.util.List;

import com.ycxw.entity.Permission;
import com.zking.util.BaseDao;
import com.zking.util.BuildTree;
import com.zking.util.PageBean;
import com.zking.util.TreeVo;

/**
 * @author 云村小威
 *
 * @2023年7月12日 上午11:11:54
 */
public class PermissionDao extends BaseDao<Permission>{

	/**
	 * 获取数据库数据
	 * @param p
	 * @param pageBean
	 * @return
	 * @throws Exception
	 */
	public List<Permission> list(Permission p, PageBean pageBean) throws Exception {
		String sql = "select * from t_oa_permission where 1=1";
		return super.executeQuery(sql, Permission.class, pageBean);
	}
	
	/**
	 * 将数据库查询的平级数据,转换成有父子关系的数据
	 * @param permission
	 * @param pageBean
	 * @return
	 * @throws Exception
	 */
	public List<TreeVo<Permission>> menus(Permission permission, PageBean pageBean) throws Exception{
		List<TreeVo<Permission>> list = new ArrayList<TreeVo<Permission>>();
		//获取的数据库集合
		List<Permission> per = this.list(permission, pageBean);
		for (Permission p : per) {
			TreeVo<Permission> vo = new TreeVo<>();
			//设置节点类内容并添加到节点集合
			vo.setId(p.getId()+"");//设置节点id 
			vo.setText(p.getName()); //设置节点文本
			vo.setParentId(p.getPid()+"");//设置父节点
			list.add(vo);
		}
		//返回节点构建好的数据
		return BuildTree.buildList(list, "-1");
	}

}

2.5 编写数据Acntion控制类

对传入节点进行Json解析,并输出到页面

package demo.web;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ycxw.dao.PermissionDao;
import com.ycxw.entity.Permission;
import com.zking.framework.ActionSupport;
import com.zking.framework.ModelDriver;
import com.zking.util.ResponseUtil;
import com.zking.util.TreeVo;
/**
 * 
 * @author 云村小威
 *
 * @2023年7月12日 上午11:31:20
 */
public class PermissionAction extends ActionSupport implements ModelDriver<Permission> {
	private Permission permission = new Permission();
	private PermissionDao dao = new PermissionDao();

	public void menus(HttpServletRequest req, HttpServletResponse resp) {
		try {
			List<TreeVo<Permission>> menus = dao.menus(null, null);
			//调用封装好的解析json类
			ResponseUtil.writeJson(resp, menus);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public Permission getModel() {
		return permission;
	}

}

将数据解析成json方法

public static void writeJson(HttpServletResponse response, Object o) throws Exception {
		ObjectMapper om = new ObjectMapper();
		// om.writeValueAsString(o)代表了json串
		write(response, om.writeValueAsString(o));
	}

3. 前台准备

3.1 配置mvc.xml文件

<action path="/permission" type="demo.web.PermissionAction"></action>

 

3.2 页面编写

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>主界面</title>
<link rel="stylesheet"
	href="${pageContext.request.contextPath}/static/js/layui/css/layui.css">
<script
	src="${pageContext.request.contextPath}/static/js/layui/layui.js"></script>
</head>
<body>
<div class="layui-layout layui-layout-admin">
  <div class="layui-header">
    <div class="layui-logo layui-hide-xs layui-bg-black">layout demo</div>
    <!-- 头部区域(可配合layui 已有的水平导航) -->
    <ul class="layui-nav layui-layout-left">
      <!-- 移动端显示 -->
      <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
        <i class="layui-icon layui-icon-spread-left"></i>
      </li>
      <!-- Top导航栏 -->
      <li class="layui-nav-item layui-hide-xs"><a href="">nav 1</a></li>
      <li class="layui-nav-item layui-hide-xs"><a href="">nav 2</a></li>
      <li class="layui-nav-item layui-hide-xs"><a href="">nav 3</a></li>
      <li class="layui-nav-item">
        <a href="javascript:;">nav groups</a>
        <dl class="layui-nav-child">
          <dd><a href="">menu 11</a></dd>
          <dd><a href="">menu 22</a></dd>
          <dd><a href="">menu 33</a></dd>
        </dl>
      </li>
    </ul>
    <!-- 个人头像及账号操作 -->
    <ul class="layui-nav layui-layout-right">
      <li class="layui-nav-item layui-hide layui-show-md-inline-block">
        <a href="javascript:;">
          <img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img">
          tester
        </a>
        <dl class="layui-nav-child">
          <dd><a href="">Your Profile</a></dd>
          <dd><a href="">Settings</a></dd>
          <dd><a href="login.jsp">Sign out</a></dd>
        </dl>
      </li>
      <li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
        <a href="javascript:;">
          <i class="layui-icon layui-icon-more-vertical"></i>
        </a>
      </li>
    </ul>
  </div>
  
  <div class="layui-side layui-bg-black">
    <div class="layui-side-scroll">
      <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
      <ul id="menu" class="layui-nav layui-nav-tree" lay-filter="menu">
       <li class="layui-nav-item layui-nav-itemed">
          <a class="" href="javascript:;">menu group 1</a>
          <dl class="layui-nav-child">
            <dd><a href="javascript:;">menu 1</a></dd>
            <dd><a href="javascript:;">menu 2</a></dd>
            <dd><a href="javascript:;">menu 3</a></dd>
            <dd><a href="">the links</a></dd>
          </dl>
        </li>
        <li class="layui-nav-item">
          <a href="javascript:;">menu group 2</a>
          <dl class="layui-nav-child">
            <dd><a href="javascript:;">list 1</a></dd>
            <dd><a href="javascript:;">list 2</a></dd>
            <dd><a href="">超链接</a></dd>
          </dl>
        </li>
        <li class="layui-nav-item"><a href="javascript:;">click menu item</a></li>
        <li class="layui-nav-item"><a href="">the links</a></li>
      </ul>
    </div>
  </div>
  
  <div class="layui-body">
    <!-- 内容主体区域 -->
    <div style="padding: 15px;">内容主体区域。记得修改 layui.css 和 js 的路径</div>
  </div>
  
  <div class="layui-footer">
    <!-- 底部固定区域 -->
            底部固定区域
  </div>
</div>
<script>
layui.use(['element', 'layer', 'util'], function(){
  var element = layui.element
  ,layer = layui.layer
  ,util = layui.util
  ,$ = layui.$;
  
   $.post("${pageContext.request.contextPath}/permission.action?methodName=menus",
	function(data){
	//将json串转换成数组对象
	var per = $.parseJSON(data);
	//拼接左侧导航栏
	var htmlStr = "";
	$.each(per,function(i,n){
		htmlStr+="<li class=\"layui-nav-item layui-nav-itemed\">";
		htmlStr+="<a class='' href=\"javascript:;\">"+n.text+"</a>";
		//判断如果子级是否有值
		if(n.hasChildren){
			var children = n.children;
			//遍历子级内容
			htmlStr+="<dl class=\"layui-nav-child\">";
			$.each(children,function(i,n){
				htmlStr+="<dd><a href=\"javascript:;\">"+n.text+"</a></dd>";
			})
			htmlStr+="</dl>";
		}
		htmlStr+="</li>";
	})
	//替换原来标签内容
	$("#menu").html(htmlStr);
	//因为要修改之前元素的内容,防止数据出不来需要进行渲染结构传入目标容器的选择器和数据。
	element.render("menu");
}) 
  
});
</script>
</body>
</html>

 注意:

防止数据出不来需要进行渲染结构传入目标容器的选择器和数据。

element.render("menu");

3.3 运行效果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/744067.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鼠标右击没有新建WORD、EXCEL、PPT选项卡解决方案

一、WinR打开运行窗口&#xff0c;输入regedit打开注册表 二、进入到相应位置&#xff0c;复制粘贴到路径处即可 ①word word&#xff1a;计算机\HKEY_CLASSES_ROOT\.docx 计算机\HKEY_CLASSES_ROOT\.doc 看你改哪个都行&#xff0c;我觉得修改第一个docx那个就行&#xff0c…

请求响应-路径参数的接收

目录 路径参数 单个路径参数地获取 多个路径参数地获取 路径参数 路径参数&#xff1a;通过URL直接传递参数&#xff0c;即参数是请求路径的一部分&#xff0c;Controller类中使用{参数名}来标识该路径参数&#xff0c;需要使用PathVarible获取路径参数 单个路径参数地获取…

密码学入门——HMAC

文章目录 一、什么是HMAC二、HMAC的步骤 一、什么是HMAC HMAC是一种使用单向散列函数来构造消息认证码的方法(RFC2104)&#xff0c;其中 HMAC的H就是Hash的意思。 HMAC 中所使用的单向散列函数并不仅限于一种&#xff0c;任何高强度的单向散列函数都可以被用于HMAC&#xff0…

基于深度学习的高精度深海鱼检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度深海鱼检测识别系统可用于检测与定位深海鱼目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的深海鱼目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型训练数据集&a…

NTP 时间戳和RTP时间戳的差异

1&#xff0c;RTP RTP全称是Real-time Transport Protocol&#xff08;实时传输协议&#xff09;&#xff0c;它是IETF提出的一个标准&#xff0c;对应的RFC文档为RFC3550。一般用其承载实时性要求很高的数据形成RTP包&#xff0c;在语音通信中&#xff0c;把PCM数据编码后得到…

微服务是SOA,微服务也不是SOA

文章目录 一、什么是SOA&#xff1f; 什么是微服务&#xff1f;SOA 和微服务的区别 公众号&#xff1a; MCNU云原生&#xff0c;文章首发地&#xff0c;欢迎微信搜索关注&#xff0c;更多干货&#xff0c;第一时间掌握&#xff01; 本文源自一次面试官的提问&#xff1a;你觉得…

和数链技术强化数字资产上链保护,确权打造数字数字资产重要防线

在互联网时代&#xff0c;版权侵权行为猖獗&#xff0c;短视频、摄影作品、电商产品详情页等频遭盗用、篡改、抄袭&#xff0c;甚至私自售卖他人的网课录屏。这些侵权行为严重扰乱市场秩序&#xff0c;严重危害了创作者的积极性。而知识产权案件的立案难、取证难、维权成本高、…

MyBatis实现动态SQL更新

博主记得在一个周五快下班的下午&#xff0c;产品找到我&#xff08;为什么总感觉周五快下班就来活 &#x1f602;&#xff09;&#xff0c;跟我说有几个业务列表查询需要加上时间条件过滤数据&#xff0c;这个条件可能会变&#xff0c;不保证以后不修改&#xff0c;这个改动涉…

Spring Boot 有哪些特点?

目录 一、自动配置 二、嵌入式 Tomcat Web 服务器 三、入门 POM 四、Actuator执行器 API 五、SpringBoot初始化器 一、自动配置 Spring Boot的自动配置是Spring Boot框架提供的一种功能&#xff0c;它可以根据用程序的依赖和配置信息&#xff0c;自动配置一些常见的功能模…

PyTorch模型容器与AlexNet构建

文章和代码已经归档至【Github仓库&#xff1a;https://github.com/timerring/dive-into-AI 】或者公众号【AIShareLab】回复 pytorch教程 也可获取。 文章目录 模型容器与AlexNet构建nn.Sequetial总结 nn.ModuleListnn.ModuleDict容器总结AlexNet实现 模型容器与AlexNet构建 …

解决固态硬盘只显示一半容量的好方法,解放隐藏的存储空间!

硬盘只显示一半容量”! “几天前&#xff0c;我的闪迪固态硬盘出现了一些奇怪的事情&#xff0c;这是个500GB的硬盘&#xff0c;但系统没有显示全部容量&#xff0c;只显示了250GB。这是什么原因&#xff1f;我该怎么办呢&#xff1f;如果大家有解决过类似问题&#xff0c;请…

使用SpringBoot+React搭建一个Excel报表平台

摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 Excel报表平台是一款功能强大、操作简单的系统平台&#xff0c;可以帮助用户上传…

海量倾斜摄影模型数据web端上传发布,在线浏览、在线分享,你还不知道吗?

倾斜摄影模型突出的特点就是数据量较大&#xff0c;这是由其高精度、对地表全覆盖的真实影像所决定的。如何将海量倾斜摄影模型数据加载到地图中并进行在线浏览是行业用户一直关心的内容&#xff0c;现在通过「四维轻云」就可以实现地理空间数据的在线管理、编辑及分享。 1、倾…

青岛大学_王卓老师【数据结构与算法】Week05_04_案例引入_学习笔记

本文是个人学习笔记&#xff0c;素材来自青岛大学王卓老师的教学视频。 一方面用于学习记录与分享&#xff0c; 另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。 如有侵权&#xff0c;请留言作删文处理。 课程视频链接&#xff1a; 数据结构与算法基础…

第二章:在html中使用javascript

1、在html页面中插入js的主要方法就是使用<script>元素 2、html4.01为<script>定义了以下6个属性&#xff1a;【language已经废弃&#xff0c;其他5个属性都是可选的】 async 表示应该立即下载脚本&#xff0c;但不应该妨碍页面中的其他操作&#xff0c;比如下载…

.NET Core 数据库DB First自动生成,Sqlite,sql server,Mysql

文章目录 前言数据库ORM代码自动添加前期准备安装Nuget Sql serverMysqlSqlite查询结果 前言 .NET Core是C# .NET 未来发展的必然趋势&#xff0c;C# 要像Java一样跨平台运行。这里解决一个.NET core 会遇到的问题&#xff0c;如何添加ORM框架。 ORM是数据库对象映射关系模型…

Anaconda的安装和配置

对于自学Python的小伙伴来说&#xff0c;在刚开始&#xff0c;我们就得要安装Python以及python的库&#xff0c;但是我们可以通过安装Anaconda很好地解决这一难题&#xff0c;给我们初学者节省很多令人头疼的环境安装问题&#xff0c;今天我就为大家分享下Anaconda的介绍&#…

什么是加密领域的 Web 3.0?

随着科技的不断进步和互联网的发展&#xff0c;我们正逐渐迈入数字经济时代。在这个时代中&#xff0c;加密领域的Web 3.0成为了一个备受关注的话题。从区块链技术到加密货币&#xff0c;从去中心化应用程序到智能合约&#xff0c;这些新兴技术正在改变着我们对互联网的认知。本…

仓库24代拣货标签——功能特点

1. 通过无线方式快速刷新屏幕&#xff1b; 2. 移动式功能用法&#xff08;自动切换基站进行通信&#xff09;&#xff1b; 3. 电量低于 50%的情况下&#xff0c;提供外接供电&#xff0c;可以对电池进行充电&#xff0c;充电时会亮红灯&#xff0c;充满后亮绿灯&#xff08;如果…

Vue3挂载全局方法及组件中如何使用

文章目录 前言一、在mian.ts&#xff08;mian.js&#xff09;中配置全局变量1、如何封装 二、如何调用1.template中调用2.在script标签中如何拿到 前言 在Vue3项目中&#xff0c;需要频繁使用某一个方法。配置到全局感觉会方便很多。 例如&#xff1a;因为很多页面都需要对时…