前言:我们实现左侧菜单栏功能,我们分析所用到的技术:json,treeov(将没有父子关系的数据转成具有父子关系的数据的方法),each遍历。
看效果:
分析思路:我们首先得获取到具有父子关系的数据,将得到的数据在页面进行遍历。
一,分析左侧菜单栏及子类的数据表
通过表的分析,此表有四个父类,每个父类对应的子类有几个,但是我们通过后台将数据传到前台必须是json格式的数据,才可以完成对应的效果。
二,实现左侧菜单栏及子类的具体步骤
2.1实体类(与数据库中的字段对应一一!!!)
/** * */ package com.zking.entity; /** * 实体类 * * @author 李永安 * * @date:2023年7月11日 下午7:00:50 * */ 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.2dao方法
我们同过json数据在线解析发现,并不是我们想要的数据!!!
这时我们得去调用框架中的TreeOv工具类 ,build工类去转化
dao类代码:
/** * */ package com.zking.dao; import java.util.ArrayList; import java.util.List; import com.zking.entity.Permission; import com.zking.util.BaseDao; import com.zking.util.BuildTree; import com.zking.util.PageBean; import com.zking.util.TreeVo; /** * 后台左侧数据显示方法 * @author 李永安 * * @date:2023年7月11日 下午7:05:31 * */ public class PermissionDao extends BaseDao<Permission>{ //获取数据库中的数据 public List<Permission> list(Permission Permission, PageBean pageBean) throws Exception { String sql = "select * from t_easyui_permission where 1=1"; return super.executeQuery(sql, Permission.class, pageBean); } public static void main(String[] args) throws Exception { System.out.println(new PermissionDao().list(new Permission(), null)); } /** * 通过Treeov将查询的数据转成具有父子级的数据 * @param Permission * @return * @throws Exception */ public List<TreeVo<Permission>> menu(Permission Permission ) throws Exception { List<TreeVo<Permission>> treeov = new ArrayList<TreeVo<Permission>>(); //数据库中的数据 List<com.zking.entity.Permission> list = this.list(Permission, null); //循环外层 for (Permission p : list) { TreeVo<Permission> treeVo = new TreeVo<>();//实例TreeVo treeVo.setId(p.getId()+"");//将p中的属性添加到TreeVo中 treeVo.setText(p.getName());//文本 treeVo.setParentId(p.getPid()+""); treeov.add(treeVo); } //调用工具类build return BuildTree.buildList(treeov, "0"); } }
TreeOv工具类代码:
package com.zking.util; import java.util.ArrayList; import java.util.List; import java.util.Map; 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(); } }
备注:TreeOv工具类:
2.3action类
/** * */ package com.zking.web; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.zking.dao.PermissionDao; import com.zking.entity.Permission; import com.zking.framework.ActionSupport; import com.zking.framework.ModelDriver; import com.zking.util.ResponseUtil; import com.zking.util.TreeVo; /** * @author 李永安 * * @date:2023年7月11日 下午8:35:18 * */ public class PermissionAction extends ActionSupport implements ModelDriver<Permission> { private Permission permission ; private PermissionDao pd = new PermissionDao(); public String menu(HttpServletRequest req, HttpServletResponse resp) throws Exception { //调用pd中的具有父子关系的数据 List<TreeVo<Permission>> menu = pd.menu(permission); ResponseUtil.writeJson(resp, menu);//用于传到jsp(data) return super.execute(req, resp); } @Override public Permission getModel() { // TODO Auto-generated method stub return permission; } }
2.4BuildTree(将不具有父子格式的数据转成具有父子格式的数据)
package com.zking.util; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class BuildTree { /** * 默认-1为顶级节点 * @param nodes * @param <T> * @return */ public static <T> TreeVo<T> build(List<TreeVo<T>> nodes) { if (nodes == null) { return null; } List<TreeVo<T>> topNodes = new ArrayList<TreeVo<T>>(); for (TreeVo<T> children : nodes) { String pid = children.getParentId(); if (pid == null || "-1".equals(pid)) { topNodes.add(children); continue; } for (TreeVo<T> parent : nodes) { String id = parent.getId(); if (id != null && id.equals(pid)) { parent.getChildren().add(children); children.setHasParent(true); parent.setChildren(true); continue; } } } TreeVo<T> root = new TreeVo<T>(); if (topNodes.size() == 1) { root = topNodes.get(0); } else { root.setId("000"); root.setParentId("-1"); root.setHasParent(false); root.setChildren(true); root.setChecked(true); root.setChildren(topNodes); root.setText("顶级节点"); Map<String, Object> state = new HashMap<>(16); state.put("opened", true); root.setState(state); } return root; } /** * 指定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) { String pid = children.getParentId(); if (pid == null || idParam.equals(pid)) { topNodes.add(children); continue; } for (TreeVo<T> parent : nodes) { String id = parent.getId(); if (id != null && id.equals(pid)) { parent.getChildren().add(children); children.setHasParent(true); parent.setChildren(true); continue; } } } return topNodes; } }
2.5配置mvc文件
<action path="/permission" type="com.zking.web.PermissionAction"> </action>
2.6jsp页面遍历数据
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/common/public.jsp"%> <!DOCTYPE> <html> <head> <script type="text/javascript"></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> //JS layui.use(['jquery'], function(){ let $ = layui.jquery; $.ajax({ url:'${pageContext.request.contextPath }/permission.action?methodName=menu', dataType:'json', method:'post', success:function(data){//数据回显 console.log(data); let htmlstr = ''; //通过each遍历 $.each(data,function(i,n){ htmlstr += '<li class="layui-nav-item layui-nav-itemed">'; htmlstr += '<a class="" href="javascript:;">'+data[i].text+'</a>'; //是否存在下一级,如果有就继续遍历 if(data[i].hasChildren){ htmlstr += '<dl class="layui-nav-child">'; let children =data[i].children; $.each(children,function(ind,nod){ htmlstr += '<dd><a href="javascript:;">'+children[ind].text+'</a></dd>'; }) htmlstr += '</dl>'; } htmlstr += '</li>'; }) //将htmlstr加入ul的id中 $("#menu").html(htmlstr); element.render('menu'); } }); }); </script> </body> </html>
注:千万不要忘了加载 element模块。
element.render('menu');
运行就可以达到效果了!!!
三,总结
学习 Layui 需要从基础的概念和用法入手,通过文档、示例和社区资源来掌握和运用 Layui 的各种功能和技巧。坚持实践和持续学习,可以帮助您逐步成为 Layui 的熟练开发者。加油!!!
好了,就讲到这里了希望这篇博客能够帮助到您!!!