这篇博客主要讲述了layUI树形菜单的各种形态以及配合MySQL数据库中的数据动态加载节点!
第一步肯定是要导入layUI的包啦!
没有的小伙伴们火速下载熬:
https://www.layui.com/
啊有一个注意事项:我在观看layUI的示例时,我只在其中看到了两个导入的路径:
但是,如果你在下载的文件里面只把layui.css和layui.js放入项目当中,如下图:
不仅效果出不来还会报错哦!这里可以看到报的是一个404错误
点进去会看到这样子一个,我大胆猜测使用layui中的tree组件是需要一个tree.js,但是这个文件在我导进去的两个文件中没有,那么为什么官方示例却又ok呢?
因为爱情?不不不,这边我找到两种解决方法:
第一,像官方示例中一样导入layui.js,但是导文件的时候将整个layui导进去。
第二,导入layui.all.js这个js文件,看到中间那个all就知道它比layui.js要高大上啦嘿嘿嘿,它会比layui.js更加全一点,我也不知道为啥要这样,我看到效果有就完了!
通过 tree.render() 方法指定一个元素,便可快速创建一个 tree 实例,我这边是模拟了一串数据,后面讲讲动态加载树形菜单熬:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Layui
tree组件的基础参数,根据需要自个调熬
首先我们得知道layui需要的数据格式是什么
还真别说,我在这里出了一个bug——tree结构动态展示出来,标题却都是未命名
主要是因为根据数据源设计节点实体类时,我为了偷懒我复制了之前做easyUI的tree组件,但是easyUI和layui的节点标题在源码中是不一样的!导致找不到标题属性就默认为‘未命名’了,可以看到我能把json弹出来:
但当我点击确认后:
1、更改源码,我刚开始居然试图弄这个,但是我承认我菜鸡我失败了,不过我找了其他人的,貌似是有成功的!
2、老老实实去节点实体类更改标题的名字,改成title~我就是使用这一种方法。
如下节点实体类:
package com.zengjing.vo;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class TreeVo {
/**
* 节点ID
*/
private String id;
/**
* 显示节点文本
*/
private String title;
/**
* 节点状态,open closed
*/
private Map state;
/**
* 节点是否被选中 true false
*/
private boolean checked = false;
/**
* 节点属性
*/
private Map attributes;
/**
* 节点的子节点
*/
private List> children = new ArrayList>();
/**
* 父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 getTitle() {
return title;
}
public void setTitle(String text) {
this.title = text;
}
public Map getState() {
return state;
}
public void setState(Map state) {
this.state = state;
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public Map getAttributes() {
return attributes;
}
public void setAttributes(Map attributes) {
this.attributes = attributes;
}
public List> getChildren() {
return children;
}
public void setChildren(List> 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 state, boolean checked, Map attributes,
List> children, boolean isParent, boolean isChildren, String parentID) {
super();
this.id = id;
this.title = 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();
}
}
BuildTree创建节点结构方法类:
package com.zengjing.vo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BuildTree {
/**
* 默认-1为顶级节点
* @param nodes
* @param
* @return
*/
public static TreeVo build(List> nodes) {
if (nodes == null) {
return null;
}
List> topNodes = new ArrayList>();
for (TreeVo children : nodes) {
String pid = children.getParentId();
if (pid == null || "0".equals(pid)) {
topNodes.add(children);
//如果是顶级节点,那么结束当前循环,继续下一次循环
continue;
}
for (TreeVo parent : nodes) {
String id = parent.getId();
if (id != null && id.equals(pid)) {
parent.getChildren().add(children);
children.setHasParent(true);
parent.setChildren(true);
continue;
}
}
}
// 考虑到一个问题,数据库表中本身没有顶级节点
TreeVo root = new TreeVo();
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.setTitle("顶级节点");
Map state = new HashMap<>(16);
state.put("opened", true);
root.setState(state);
}
return root;
}
/**
* 指定idparam为顶级节点
* @param nodes
* @param idParam
* @param
* @return
*/
public static List> buildList(List> nodes, String idParam) {
if (nodes == null) {
return null;
}
List> topNodes = new ArrayList>();
for (TreeVo children : nodes) {
String pid = children.getParentId();
if (pid == null || idParam.equals(pid)) {
topNodes.add(children);
continue;
}
for (TreeVo 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;
}
}
节点实体类创建后,就在dao层创建一个将数据库的数据通过BuildTree解析为json格式返回,,
public List> toNode(Menu menu,PageBean pageBean) throws Exception {
List
再在action中输出为json串到前端:
public String menuTree(HttpServletRequest req,HttpServletResponse resp) {
try {
ResponseUtil.writeJson(resp, this.md.toNode(null, null));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
writeJson方法内容:
public static void writeJson(HttpServletResponse response,Object o)throws Exception{
response.setContentType("text/html;charset=utf-8");
ObjectMapper om = new ObjectMapper();
String jsonstr = om.writeValueAsString(o);
PrintWriter out=response.getWriter();
out.println(jsonstr.toString());
out.flush();
out.close();
}
后台获取json数据结束,就到了重点的前端,我是通过一个函数使用了ajax获取后台数据,再进行返回,在tree的数据源后直接调用方法即可,我的jsp界面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Layui
最后效果图:
前端果然是一个考验人耐心的东西,呜呜呜,写前端样式有问题一定记得清缓存!!好几次因为这个卡好久了,还有记得不同前端框架的文档肯定有一点差异,不要盲目c代码,我今天就直接血的教训,有问题欢迎指教哦摆摆!