1.什么是layui:
Layui是一个简单、易用且功能强大的前端UI框架,专注于提升开发者的开发效率。它基于HTML、CSS和JavaScript,并提供了一套丰富的UI组件、动态模块加载、模板引擎、弹窗组件、表单验证等等功能,可以帮助开发者快速构建漂亮、响应式的Web界面。
Layui的设计理念是"经典易用,显而易见",具有简洁、直观的API,可以很容易地理解和使用。它提供了灵活的扩展机制和丰富的文档,能够满足各种项目的需求,并且可以与主流的JavaScript库和框架(如jQuery、AngularJS等)无缝集成。
通过使用Layui,开发者可以快速搭建出结构清晰、交互友好、美观大方的Web界面,提高开发效率,节省开发时间。无论是个人项目还是企业级应用,Layui都是一个不错的选择。
2.原始数据获取:
1.需要什么样的数据格式:
oneitems=[ {name:'group1',id=1,haschild:true,child=flase} {name:'menu1',id=1}, {name:'menu2',id=2}, {name:'menu3',id=3}, ]}, {name:'group2',id=2}, {name:'group3',id=3}, {name:'group',id=4},
2.能够拿到什么样的数据:
建立实体类:
package com.zking.entity; 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 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; } public Permission() { super(); } @Override public String toString() { return "Permission [id=" + id + ", name=" + name + ", description=" + description + ", url=" + url + ", pid=" + pid + ", ismenu=" + ismenu + ", displayno=" + displayno + "]"; } }
建立dao方法:
package com.zking.dao; import java.util.List; import com.zking.entity.Permission; import com.zking.util.BaseDao; import com.zking.util.PageBean; public class PermissionDao extends BaseDao<Permission> { public List<Permission> list(Permission permission, PageBean pageBean) throws Exception { String sql="select * from t_oa_permission"; return super.executeQuery(sql, Permission.class, pageBean); } }
使用junit4来看获取什么:
package com.zking.dao; import static org.junit.Assert.*; import java.util.List; import org.junit.Test; import com.fasterxml.jackson.databind.ObjectMapper; import com.zking.entity.Permission; public class PermissionDaoTest { private PermissionDao permissionDao =new PermissionDao(); @Test public void testList() throws Exception { List<Permission> list = permissionDao.list(null, null); ObjectMapper om=new ObjectMapper(); System.out.println(om.writeValueAsString(list)); } }
最后输出结果:
[{ "id": 10, "name": "会议管理", "description": null, "url": null, "pid": -1, "ismenu": 1, "displayno": 1 }, { "id": 11, "name": "投票管理", "description": null, "url": null, "pid": -1, "ismenu": 1, "displayno": 9 }, { "id": 12, "name": "会议室管理", "description": null, "url": "jsp/meeting/meetingRoom.jsp", "pid": -1, "ismenu": 1, "displayno": 14 }, { "id": 13, "name": "系统管理", "description": null, "url": null, "pid": -1, "ismenu": 1, "displayno": 15 }, { "id": 1001, "name": "会议发布", "description": "发起会议", "url": "jsp/meeting/addMeeting.jsp", "pid": 10, "ismenu": 1, "displayno": 2 }, { "id": 1002, "name": "会议通知", "description": "别人发起的会议,需要你确认是否参加", "url": "jsp/meeting/meetingNotify.jsp", "pid": 10, "ismenu": 1, "displayno": 3 }, { "id": 1003, "name": "我的会议", "description": "我发起的,未审核->已审核", "url": "jsp/meeting/myMeeting.jsp", "pid": 10, "ismenu": 1, "displayno": 4 }, { "id": 1004, "name": "我的审批", "description": "我审批的会议", "url": "jsp/meeting/myAudit.jsp", "pid": 10, "ismenu": 1, "displayno": 5 }, { "id": 1005, "name": "待开会议", "description": "我参与的,但是还未开始的", "url": "jsp/meeting/meetingWaiting.jsp", "pid": 10, "ismenu": 1, "displayno": 6 }, { "id": 1006, "name": "历史会议", "description": "已经参与的", "url": "jsp/meeting/meetingHistory.jsp", "pid": 10, "ismenu": 1, "displayno": 7 }, { "id": 1007, "name": "所有会议", "description": "对所有会议进行汇总", "url": "jsp/meeting/meetingAll.jsp", "pid": 10, "ismenu": 1, "displayno": 8 }, { "id": 1101, "name": "投票标题", "description": "需要关联到会议标题(议题)", "url": null, "pid": 11, "ismenu": 1, "displayno": 10 }, { "id": 1102, "name": "投票选项", "description": "需要关联到投票标题", "url": null, "pid": 11, "ismenu": 1, "displayno": 11 }, { "id": 1103, "name": "投票结果", "description": "需要保留数据,可以看到谁投了什么票", "url": null, "pid": 11, "ismenu": 1, "displayno": 12 }, { "id": 1104, "name": "投票报表", "description": "哪标题的哪个选项共投了多少票", "url": null, "pid": 11, "ismenu": 1, "displayno": 13 }, { "id": 1301, "name": "用户管理", "description": null, "url": "jsp/system/userManage.jsp", "pid": 13, "ismenu": 1, "displayno": 16 }, { "id": 1302, "name": "角色管理", "description": null, "url": null, "pid": 13, "ismenu": 1, "displayno": 17 }, { "id": 1303, "name": "权限管理", "description": null, "url": null, "pid": 13, "ismenu": 1, "displayno": 18 }, { "id": 1304, "name": "数据字典", "description": null, "url": null, "pid": 13, "ismenu": 1, "displayno": 19 }]
3.layui父子数据的转换:
树型菜单展示 泛型 帮助形成父子关系的一个类:建立TreeVo
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(); } }
将数据库查询出来的平级数据,转换成有父子关系的数据:
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; public class PermissionDao extends BaseDao<Permission> { public List<Permission> list(Permission permission, PageBean pageBean) throws Exception { String sql="select * from t_oa_permission"; return super.executeQuery(sql, Permission.class, pageBean); } //将数据库查询出来的平级数据,转换成有父子关系的数据 public List<TreeVo<Permission>> menus(Permission permission, PageBean pageBean) throws Exception{ List<TreeVo<Permission>> l=new ArrayList<TreeVo<Permission>>(); List<Permission> list = this.list(permission, pageBean); for (Permission p : list) { TreeVo<Permission> vo = new TreeVo<>(); vo.setId(p.getId()+""); vo.setText(p.getName()); vo.setParentId(p.getPid()+""); l.add(vo); } return BuildTree.buildList(l, "-1"); } }
使用junit4来获取父子关系:
package com.zking.dao; import static org.junit.Assert.*; import java.util.List; import org.junit.Test; import com.fasterxml.jackson.databind.ObjectMapper; import com.zking.entity.Permission; import com.zking.util.TreeVo; public class PermissionDaoTest { private PermissionDao permissionDao =new PermissionDao(); @Test public void testList() throws Exception { List<Permission> list = permissionDao.list(null, null); ObjectMapper om=new ObjectMapper(); System.out.println(om.writeValueAsString(list)); } @Test public void menus() throws Exception { List<TreeVo<Permission>> menus = permissionDao.menus(null, null); ObjectMapper om=new ObjectMapper(); System.out.println(om.writeValueAsString(menus)); } }
输出结果:
[{ "id": "10", "text": "会议管理", "state": null, "checked": false, "attributes": null, "children": [{ "id": "1001", "text": "会议发布", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "10", "hasParent": true, "hasChildren": false }, { "id": "1002", "text": "会议通知", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "10", "hasParent": true, "hasChildren": false }, { "id": "1003", "text": "我的会议", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "10", "hasParent": true, "hasChildren": false }, { "id": "1004", "text": "我的审批", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "10", "hasParent": true, "hasChildren": false }, { "id": "1005", "text": "待开会议", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "10", "hasParent": true, "hasChildren": false }, { "id": "1006", "text": "历史会议", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "10", "hasParent": true, "hasChildren": false }, { "id": "1007", "text": "所有会议", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "10", "hasParent": true, "hasChildren": false }], "parentId": "-1", "hasParent": false, "hasChildren": true }, { "id": "11", "text": "投票管理", "state": null, "checked": false, "attributes": null, "children": [{ "id": "1101", "text": "投票标题", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "11", "hasParent": true, "hasChildren": false }, { "id": "1102", "text": "投票选项", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "11", "hasParent": true, "hasChildren": false }, { "id": "1103", "text": "投票结果", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "11", "hasParent": true, "hasChildren": false }, { "id": "1104", "text": "投票报表", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "11", "hasParent": true, "hasChildren": false }], "parentId": "-1", "hasParent": false, "hasChildren": true }, { "id": "12", "text": "会议室管理", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "-1", "hasParent": false, "hasChildren": false }, { "id": "13", "text": "系统管理", "state": null, "checked": false, "attributes": null, "children": [{ "id": "1301", "text": "用户管理", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "13", "hasParent": true, "hasChildren": false }, { "id": "1302", "text": "角色管理", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "13", "hasParent": true, "hasChildren": false }, { "id": "1303", "text": "权限管理", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "13", "hasParent": true, "hasChildren": false }, { "id": "1304", "text": "数据字典", "state": null, "checked": false, "attributes": null, "children": [], "parentId": "13", "hasParent": true, "hasChildren": false }], "parentId": "-1", "hasParent": false, "hasChildren": true }]
4.layui功能实现:
配置mvc.xml:
<?xml version="1.0" encoding="UTF-8"?> <config> <action path="/blog" type="com.zking.web.BlogAction"> <forward name="list" path="/blogList.jsp" redirect="false" /> <forward name="toList" path="/blog.action?methodName=list" redirect="true" /> <forward name="toEdit" path="/blogEdit.jsp" redirect="false" /> </action> <action path="/user" type="com.zking.web.UserAction"> </action> <action path="/permission" type="com.zking.web.PermissionAction"> </action> <!-- <action path="/meetingInfo" type="com.zking.web.MeetingInfoAction"> --> <!-- <forward name="list" path="/meetingInfoList.jsp" redirect="false" /> --> <!-- <forward name="toList" path="/meetingInfo.action?methodName=list" --> <!-- redirect="true" /> --> <!-- <forward name="toEdit" path="/meetingInfoEdit.jsp" redirect="false" /> --> <!-- </action> --> <!-- <action path="/solrBlog" type="com.test.web.SolrBlogAction"> --> <!-- <forward name="list" path="/solrBlogList.jsp" redirect="false" /> --> <!-- <forward name="toList" path="/solrBlog.action?methodName=list" --> <!-- redirect="true" /> --> <!-- <forward name="toEdit" path="/solrBlogEdit.jsp" redirect="false" /> --> <!-- </action> --> <action path="/studentBlog" type="com.test.web.StudentBlogAction"> <forward name="list" path="/studentBlogList.jsp" redirect="false" /> <forward name="toList" path="/studentBlog.action?methodName=list" redirect="true" /> <forward name="toEdit" path="/studentBlogEdit.jsp" redirect="false" /> </action> <action path="/solrBlog" type="com.xiaoli.web.SolrBlogAction"> <forward name="list" path="/solrBlogList.jsp" redirect="false" /> <forward name="toList" path="/solrBlog.action?methodName=list" redirect="true" /> <forward name="toEdit" path="/solrBlogEdit.jsp" redirect="false" /> </action> </config>
前台:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="common/header.jsp" %> <!DOCTYPE html > <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>后台主页</title> </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(['element', 'layer', 'util'], function(){ var element = layui.element ,layer = layui.layer ,util = layui.util ,$ = layui.$; $.ajax({ url:"${pageContext.request.contextPath }/permission.action?methodName=menus", dataType:'json', success:function(data){ console.log(data); var htmlStr=''; $.each(data,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(idx,node){ htmlStr +=' <dd><a href="javascript:;">'+node.text+'</a></dd>'; }) htmlStr +=' </dl>'; } htmlStr +=' </li>'; }) $("#menu").html(htmlStr); element.render('menu'); } }); }); </script> </body> </html>
最后一定要:
加 element.render('menu')要不然会报错
输出结果: