Layui之动态树 左侧树形菜单栏 详细全面

⭐ฅʕ•̫͡•ʔฅ本期看点:该篇是运用Layui框架来编写后台树形菜单栏,并且结合MySql来编写完成

目录

一.效果图

二.具体步骤

 2.1 数据库 

 2.2 树形导航栏

    第一个类:Treevo

             第二个类:BuildTree:

2.3  Dao方法

        2.3.1 basedao

                 2.3.2 Dao类

2.4  后台Servlet

2.5 前台代码


一.效果图

Layui就一般都为这种水墨风,哈哈,大概就是图片的左侧的样子

二.具体步骤

 2.1 数据库 

        需要准备的数据:首先准备好需要展示在树形菜单中的数据。这些数据应该包含节点的id、父节点id、节点名称等信息,以便构建树形结构。

Layui之动态树 左侧树形菜单栏 详细全面_第1张图片

 2.2 树形导航栏

 写一个java文件,里面包含了所有关于树形导航栏的方法和属性,把关于导航栏的单独用一个类写出,这样会更加清晰明了

    第一个类:Treevo:

        这个里面定义了许多关于父节点以及子节点的属性,可以帮助我们在将数据库的平级数据转换成父子关系的数据 ,以及定义了两个属性是否有父节点,子节点,将来要进行判断

package com.zking.util;

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


public class TreeVo {
	/**
	 * 节点ID
	 */
	private String id;
	/**
	 * 显示节点文本
	 */
	private String text;
	/**
	 * 节点状态,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 getText() {
		return text;
	}

	public void setText(String text) {
		this.text = 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.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();
	}

}

第二个类:BuildTree:

        这个类里面定义了两个循环,一个循环可视为外层循环,即可定义为将所有的数据循环一遍,接着第二个循环可视为内层循环,将第二个循环的父id和第一个循环的id进行判断,如果相等就说明 他们是父子关系,并且在这里还指定了默认最高节点也就是父节点,这个可根据自己的数据库里的来进行变化

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 
	 * @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("0");
			root.setHasParent(false);
			root.setChildren(true);
			root.setChecked(true);
			root.setChildren(topNodes);
			root.setText("顶级节点");
			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;
	}

}

2.3  Dao方法

        2.3.1 basedao

package com.yinzi.utils;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.yinzi.utils.DBAccess;
import com.yinzi.utils.PageBean;

public class BaseDao {
	/**
	 * 带分页的模糊查询
	 * @param c
	 * @param sql
	 * @param pagebean
	 * @return
	 * @throws Exception
	 */
	public List executeQuery(Class c ,String sql,PageBean pagebean) throws Exception{
		//创建集合保存数据
		List list = new ArrayList<>();
		//获取连接
		Connection conn =null;
		//执行SQL语句
		PreparedStatement ps = null;
		//结果集对象
		ResultSet rs =null;
		
		//判断是否需要分页
		if(pagebean!=null && pagebean.isPagination()) {//如果需要分页,就拼接SQL语句
			String Countsql=getCountsql(sql);//获取总数量
			conn = DBAccess.getConnection();
			ps = conn.prepareStatement(Countsql);//执行改变后的SQL语句
			rs = ps.executeQuery();
			if(rs.next()) {
				pagebean.setTotal(rs.getObject("n").toString());
			}
			
			String pagesql=getPagesql(sql,pagebean);
			conn = DBAccess.getConnection();
			ps = conn.prepareStatement(pagesql);//执行改变后的SQL语句
			rs = ps.executeQuery();
		}else {//否则不需要,就按照原sql语句执行
			conn = DBAccess.getConnection();
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
		}
		
		//循环遍历数据
		while(rs.next()) {
			T t = (T) c.newInstance();
			//拿到所有的属性
			Field[] fields = c.getDeclaredFields();
			for (Field field : fields) {
				//打开访问权限
				field.setAccessible(true);
				field.set(t,rs.getObject(field.getName()));
			}
			list.add(t);
		}
		return list;
	}
	/**
	 * 最终SQL语句
	 * @param sql
	 * @param pagebean
	 * @return
	 */
	private String getPagesql(String sql, PageBean pagebean) {
		return sql+" limit "+pagebean.getStartIndex()+","+pagebean.getRows();
	}
	/**
	 * 总记录数
	 * @param sql
	 * @return
	 */
	private String getCountsql(String sql) {
		return "select count(1) as n from ("+sql+") t";
		
	}
	
	
	
	
	
	/**
	 *  增删改的方法
	 * @param sql sql语句
	 * @param t 实体类
	 * @param attr 实体类对应的属性
	 * @return
	 * @throws Exception 
	 */
	public int excuteUpdate(String sql ,T t,String[] attr) throws Exception {
		Connection conn=DBAccess.getConnection();//连接数据库
		PreparedStatement ps=conn.prepareStatement(sql);//执行sql语句
		//循环拿到属性
		for (int i = 0; i < attr.length; i++) {
			//一切反射从获取类类开始
			Field f = t.getClass().getDeclaredField(attr[i]);
			//打开访问权限
			f.setAccessible(true);
			ps.setObject(i+1, f.get(t));
		}
		
		return ps.executeUpdate();
		
	}
	
	
	
	
	
	
	
}

2.3.2 Dao类

        这个类里面首先做了一个查询所有获取所有的数据,接着 写一个方法将这些平级的数据转换成父子关系的数据,还调用了BuildTree里面的方法

package com.yinzi.dao;

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

import org.junit.Test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yinzi.entity.Permission;
import com.yinzi.utils.BaseDao;
import com.yinzi.utils.PageBean;
import com.zking.util.BuildTree;
import com.zking.util.TreeVo;

public class PermissionDao extends BaseDao{
	/**
	 * 查詢所有
	 * @param permission
	 * @param pagebean
	 * @return
	 * @throws Exception
	 */
	public List list(Permission permission,PageBean pagebean) throws Exception {
		String sql="select * from t_easyui_permission";
		return super.executeQuery(Permission.class, sql, pagebean);
	}
	
	
	
	//将这些平级数据转换成父子关系的数据
	public List> menus(Permission permission,PageBean pagebean) throws Exception{
		//创建一个父子关系的集合  TreeVo
		List> tvList = new ArrayList>();
		//获取平级数据
		List list = this.list(permission, pagebean);
		for (Permission per : list) {
			TreeVo tv=new TreeVo<>();
			//将per对象转成tv对象,因为tv对象才有children
			tv.setId(per.getId()+"");
			tv.setText(per.getName());
			tv.setParentId(per.getPid()+"");
			tvList.add(tv);
		}
		return BuildTree.buildList(tvList, "0");//这个地方填写一级菜单的id
	}
	
	
	

	
	
	
}

2.4  后台Servlet

package com.yinzi.Servlet;

import java.util.List;

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

import com.yinzi.dao.PermissionDao;
import com.yinzi.entity.Permission;
import com.zking.framework.ActionSupport;
import com.zking.framework.ModelDriver;
import com.zking.util.ResponseUtil;
import com.zking.util.TreeVo;

public class PermissionAction extends ActionSupport implements ModelDriver{
	private Permission permission=new Permission();
	private PermissionDao pd=new PermissionDao();
	
	public void menus(HttpServletRequest req, HttpServletResponse resp) throws Exception {
		//调用方法
		List> menus = pd.menus(null, null);
		//回显给前台
		ResponseUtil.writeJson(resp, menus);
	}
	
	@Override
	public Permission getModel() {
		return permission;
	}

}

2.5 前台代码

        首先样式小编是复制的Layui的模式,然后在ajax里面进行了拼接循环,最后输出即可

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




后台首页







今天的分享的案例就到这啦,有不懂的宝子,评论区留言,尽情期待哦~~

你可能感兴趣的:(layui,前端,javascript,java,数据库,mysql)