Ztree

本文详细介绍Ztree树形控件的特性、优势及应用,包括优异性能、灵活配置和多功能组合,适用于树状菜单、数据展示及权限管理等项目开发场景。文章涵盖官网资源、关键代码、常见问题解决方案及后端数据处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Ztree 是一种树形展示,当你用新型前端框架的时候,你就意味着要学习他的树形展示,但是Ztree它单独自成一体,这样就不用总是学习别的树形展示了,学会Ztree,可以通用;
优点:
1.优异的性能
2.灵活的配置
3.多种功能的组合

适合项目开发
1.树状菜单
2.树状数据的Web显示
3.权限管理等等。

特点:
● zTree v3.0 将核心代码按照功能进行了分割,不需要的代码可以不用加载

● 采用了延迟加载技术,上万节点轻松加载,即使在 IE6 下也能基本做到秒杀

● 兼容 IE、FireFox、Chrome、Opera、Safari 等浏览器

● 支持 JSON 数据

● 支持静态和 Ajax 异步加载节点数据

● 支持任意更换皮肤 / 自定义图标(依靠css)

● 支持极其灵活的 checkbox 或 radio 选择功能

● 提供多种事件响应回调

● 灵活的编辑(增/删/改/查)功能,可随意拖拽节点,还可以多节点拖拽哟

● 在一个页面内可同时生成多个 Tree 实例

● 简单的参数配置实现 灵活多变的功能
一、网站地址
1.Ztree官网:(官网API文档以及Demo演示项方法介绍比较详细)(重点)
http://www.treejs.cn/v3/main.php#_zTreeInfo
2.进阶学习网页原地址:(学习博客)
http://www.cnblogs.com/sylvandu/p/5805592.html
3.入门学习网页原地址:(学习博客)
https://www.toutiao.com/a6519719172337828365/
4. 资源下载地址:(文件夹已有名称为:zTree资料包)(重点)
https://gitee.com/zTree/zTree_v3
5.JQUery下载官网:
https://code.jquery.com/jquery/
6.为知个人笔记(可以把需要记录的笔记写在里面)
https://note.wiz.cn/
7.zTree贴吧 (百度贴吧)
https://tieba.baidu.com/f?kw=ztree

二、关键性代码

zTree加载需要注意的地方
简单格式:
必须项 :
是否为父节点Isparent、节点id、 节点Pid、节点名name
次需 :
是否打开(针对于父节点) open、参数 attribute
扩展项:
icon 图片等等
基本格式:
必须项 :
是否为父节点Isparent、节点id、 节点Pid、节点名name
Children 子级节点集合。
次需:
是否打开(针对于父节点) open、参数 attribute
扩展项目:……
2.初始化zTree方法
介绍 :万物(恶)之源
简介:这个方法是用来加载指定JSON数据的,nodes则是数据名
.fn.zTree.init( .fn.zTree.init(.fn.zTree.init(("#treeDemo"), setting,nodes);

简介:这个方法时拿来加载数据库的无需nodes
.fn.zTree.init( .fn.zTree.init(.fn.zTree.init(("#treeDemo"), setting); //arg1:zTree对象页面展示ID,arg2 ztree展示设置。

三、踩到的坑
1.前端F12调试控制台显示:$… is not a function
这个错误弄了半个小时,因为什么呢?因为zTree和EasyUi各有JQuery文件,因为各自都依赖于JQuery,所以里面的JQuery版本不一样,导入的JQuery文件冲突,删除EasyUi里的JQuery就行了。
也有另外一个原因,是因为进行上一步操作后JQuery顺序不正确。
PS:所以直接把JQuery导入放到第一个,这就万无一失了。

2.空的父节点无限重新加载tree
当然我写的这个问题的解决方法,只针对于你做zTree菜单并且使用简单JSON格式方法去展示的时候,当你点开一个空的父节点的时候,它会又把当前的这个tree菜单又加载一遍,然后作为这个空父节点的子节点展示出来,如果遇到这种问题,请你放弃使用简单格式,老老实实用普通JSON格式。

错误图片(来自前端F12调试的控制台):
在这里插入图片描述

控制台的Bug:
在这里插入图片描述
这个错误挺有意识的,为什么会出现这个错误呢,仔细看你异步加载时候提交方式如何设置的就知道了,当提交方式为get它就来这个错误了,改成post就没有问题了。
四、 子节点无法找到父节点
这个问题也是出现在你使用简单JSON格式来展示你的tree的时候,因为简单格式的ztree 后端返回的JSOn格式并没有定义children这个属性,但是ztree它是可以通过设置支持简单格式的。如图:
在这里插入图片描述

当你设置enable为false,它的子节点的就无法查询到父节点了,所以你把enable 设置为 true ,就?了。

Ztree 的Dao层

/**

  • 树形菜单Ztree数据访问层
  • @author Administrator

*/
public class ZtreeDao extends JSonBaseDao {

// 第一种 : 简单JSOn格式,通过pid以及id判断
/**
 * 拿到菜单栏
 * 
 * @param parameter
 * @return
 * @throws SQLException
 * @throws InstantiationException
 * @throws IllegalAccessException
 * @throws NoSuchFieldException
 * @throws SecurityException
 */
private List<Map<String, Object>> menuList(Map<String, String[]> parameter) throws SQLException,
		InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
	String sql = "select * from tb_ztree_menu where true";
	String parentid = JSonUtil.getReqParameter(parameter, "parentid");
	if (StringUtils.isNotBlank(parentid)) {
		sql += " and parentid = " + parentid;
	}

	return super.executeQuery(sql, null);
}

/**
 * 将数据库查找出的数据转换为可展示数据
 * 
 * @param map
 * @param ztreeNode
 */
private void menuToJson(List<Map<String, Object>> menuList, List<ZtreeNode> ztreeNodeList) {
	ZtreeNode ztreeNode = null;
	if (menuList != null && menuList.size() > 0) {
		for (Map<String, Object> map : menuList) {
			ztreeNode = new ZtreeNode();
			ztreeNode.setId(Integer.valueOf(map.get("menuId").toString()));
			ztreeNode.setpId(Integer.valueOf(map.get("parentId").toString()));
			ztreeNode.setName(map.get("menuName").toString());
			ztreeNode.setIsParent(map.get("isParent").toString());
			ztreeNode.setOpen(map.get("isParent").toString());
			ztreeNode.setAttribute(map);
			ztreeNodeList.add(ztreeNode);
		}
	}
}

/**
 * 子控制器调用该查询方法
 * 
 * @param parameter
 * @return
 * @throws SQLException
 * @throws SecurityException
 * @throws NoSuchFieldException
 * @throws IllegalAccessException
 * @throws InstantiationException
 */
public List<ZtreeNode> menuJsonList(Map<String, String[]> parameter) throws InstantiationException,
		IllegalAccessException, NoSuchFieldException, SecurityException, SQLException {
	List<Map<String, Object>> menuList = this.menuList(parameter);
	List<ZtreeNode> ztreeNodeList = new ArrayList<>();
	this.menuToJson(menuList, ztreeNodeList);
	return ztreeNodeList;
}

// -----------------------------
// 第二种:标准JSOn格式,标准的 JSON 数据需要嵌套表示节点的父子包含关系

/**
 * 将数据库所有的数据加载出来
 * 
 * @param parameter
 * @param pageBean
 * @return
 * @throws InstantiationException
 * @throws IllegalAccessException
 * @throws NoSuchFieldException
 * @throws SecurityException
 * @throws SQLException
 */
public List<Map<String, Object>> menuList(Map<String, String[]> parameter, PageBean pageBean)
		throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException,
		SQLException {
	String sql = "select * from tb_ztree_menu where true";
	String menuId = JSonUtil.getReqParameter(parameter, "menuId");
	if (StringUtils.isNotBlank(menuId)) {
		sql += " and parentId in ( " + menuId + ")";
	} else {
		sql += " and parentId = -1";
	}
	return super.executeQuery(sql, null);
}

/**
 * 步骤: 一.查询所有的信息 二.直接查出来的数据不能展示,然后就需要将所有的数据转换成可展示数据 1.添加所有数据Node
 * 2.如果当前节点是父节点,则用递归添加子节点 3.写方法啊,还看什么 三.递归方法 四.展示方法
 * 
 */

/**
 * 将对象转换成可以展示的对象,此方法只针对于当前对象。 使用递归方法将所有对象转换完毕。
 * 
 * @param menuList
 * @param treeNode
 * @throws SQLException
 * @throws SecurityException
 * @throws NoSuchFieldException
 * @throws IllegalAccessException
 * @throws InstantiationException
 */
public void menuToNode(Map<String, Object> map, ZtreeNode ztreeNode) throws InstantiationException,
		IllegalAccessException, NoSuchFieldException, SecurityException, SQLException {
	// 添加相应的值
	ztreeNode.setId(Integer.valueOf(map.get("menuId").toString()));
	ztreeNode.setpId(Integer.valueOf(map.get("parentId").toString()));
	ztreeNode.setName(map.get("menuName").toString());
	ztreeNode.setIsParent(map.get("isParent").toString());
	ztreeNode.setAttribute(map);
	// 定义数组(用来装载转换后的当前父节点的子节点对象数组)
	List<ZtreeNode> treeNodeList = new ArrayList<>();

	// 定义一个参数数组并且赋予当前节点的Id,用来查询当前父节点的子节点对象
	Map<String, String[]> paramMap = new HashMap<>();
	paramMap.put("menuId", new String[] { ztreeNode.getId() + "" });
	// 开始查询当前父节点的子节点对象、并拿到返回集合
	List<Map<String, Object>> menuChildrenList = this.menuList(paramMap, null);
	// 如果该节点有子节点,那么就得进行子节点的转换操作 通俗点就是如果有儿子就要把儿子丢进去转换一波
	if (menuChildrenList != null && menuChildrenList.size() > 0) {
		ztreeNode.setIsParent("true");//不管数据库是否false与true,只要有子节点,那么设置它是父节点
		ztreeNode.setOpen("true");//设置自动展开
		// 把子节点对象丢过去转换一波
		this.menuListToNodeList(menuChildrenList, treeNodeList);
	}
	// 这里是没有儿子的情况,当父节点没有儿子的时候,我们就把它的自动展开给覆盖,让它不自动展开
	else {
		ztreeNode.setOpen("false");// 是否默认打开跟是否为父节点时一样的,也就是打开所有父节点
	}
	// 将子节点对象添加到treeNode
	ztreeNode.setChildren(treeNodeList);
}

/**
 * 将当前父节点里所有的子节点转换成可以展示的对象,此方法只针对于当前父节点对象的子节点。
 * 
 * @param menuList
 * @param treeNodeList
 * @throws SQLException
 * @throws SecurityException
 * @throws NoSuchFieldException
 * @throws IllegalAccessException
 * @throws InstantiationException
 */
public void menuListToNodeList(List<Map<String, Object>> menuList, List<ZtreeNode> treeNodeList)
		throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException,
		SQLException {
	ZtreeNode treeNode = null;// 先声明一个对象
	// 将参数menuList父节点的子节点遍历
	for (Map<String, Object> tree : menuList) {
		treeNode = new ZtreeNode();// 这里实例出来
		// 当前对象(也就是当前父节点下所有的子节点),转换为可以展示的对象
		// tree代表当前对象 treeNode代表转换后的对象
		this.menuToNode(tree, treeNode);
		// 然后将转换后的对象添加到集合里面去
		treeNodeList.add(treeNode);
	}
}

/**
 * 展示方法 Action调用该方法
 * 
 * @param parameter
 * @param pageBean
 * @return
 * @throws InstantiationException
 * @throws IllegalAccessException
 * @throws NoSuchFieldException
 * @throws SecurityException
 * @throws SQLException
 */
public List<ZtreeNode> menuTreeList(Map<String, String[]> parameter, PageBean pageBean)
		throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException,
		SQLException {
	// 首先调用查询方法把数据从数据库查出
	List<Map<String, Object>> menuList = this.menuList(parameter, pageBean);
	// 定义菜单数组
	List<ZtreeNode> treeNodeList = new ArrayList<>();
	// 转换一波
	this.menuListToNodeList(menuList, treeNodeList);
	return treeNodeList;// 返回数组,该数组即是所需数组
}
// -----------------------------

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值