前言
在前端开发过程中,树形控件是比较常用的控件之一。而Layui框架中,也提供了基于jQuery的树形控件。除了普通的静态树形外,Layui还提供了动态树形。在本篇博客中,我将详细介绍Layui的动态树形控件。
一、什么是动态树形?
动态树形是指树形结构中的节点是动态生成的,而不是在页面初始化时就固定好的。在用户进行某些操作(如展开或折叠节点、勾选或取消勾选节点)时,会向后台发送请求,然后根据后台返回的数据重新生成新的树形结构。这样做的好处是,可以避免在页面初始化时一次性加载所有节点而导致页面加载缓慢,同时也能够节省服务器资源。
二、Layui动态树形基本使用
在Layui中,要使用动态树形,需要依赖两个模块,即Tree(树形组件)和Xtree(树形组件的扩展)。
引入CSS和JavaScript
首先,在页面的标签内引入需要的CSS和JavaScript文件。
<script src="https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js"></script> <link rel="stylesheet" href="https://cdn.staticfile.org/layui/2.5.6/css/layui.min.css"> <script src="https://cdn.staticfile.org/layui/2.5.6/layui.min.js"></script>
HTML结构
接着,在页面中定义树形结构的HTML结构。
这里我们使用一个div作为树形结构的容器,通过id属性来标识。
JavaScript代码
在完成HTML结构的定义后,我们需要编写一些JavaScript代码来初始化树形结构。具体来说,需要实例化Tree和Xtree两个对象,并将它们绑定到相应的HTML元素上。
layui.use(['tree', 'xtree'], function () { var tree = layui.tree; var xtree = layui.xtree; // 实例化tree tree.render({ elem: '#test', // 绑定HTML元素 data: [], // 数据 id: 'testTree', // id属性 showCheckbox: true, // 是否显示复选框 accordion: true, // 是否开启手风琴模式 }); // 实例化xtree xtree.render({ elem: '#test', // 绑定HTML元素 data: [], // 数据 ckall: true, // 是否开启全选 icon: { // 自定义图标 open: '', close: '', }, }); });
在上面的代码中,我们首先使用了layui.use方法来加载所需要的模块。然后,我们实例化了tree和xtree两个对象,并调用它们的render方法来初始化树形结构。其中,elem属性指定要绑定的HTML元素;data属性指定树形的数据;id属性用于标识树形;showCheckbox属性用于控制是否显示复选框;accordion属性用于控制是否开启手风琴模式。另外,我们还可以使用xtree的ckall属性来控制是否开启全选,以及使用icon属性来自定义图标。
三、动态加载数据
在了解了Layui动态树形的基本使用之后,接下来我们将介绍如何动态加载数据。
在Layui中动态加载数据需要借助异步接口,即通过向后台发送请求获取数据并动态生成树形结构。实现动态树形加载的方式有多种,比如使用jQuery的AJAX方法来发送异步请求,或者直接使用Layui的自带异步接口来实现。下面,我们将通过一个示例来介绍如何使用Layui的自带异步接口来实现动态树形加载。
后台数据格式
首先,需要定义后台返回的数据格式。在Layui中,异步接口返回的数据格式为JSON格式,因此我们需要使用JSON格式来定义数据。JSON格式的具体定义可以参考代码中的注释。
{ "code": 0, // 后台返回数据的状态码(0表示成功,其它表示失败) "msg": "", // 后台返回的消息 "data": [ // 返回的数据 { "title": "父节点1", // 节点名称 "id": "1", // 节点id "children": [ // 子节点 { "title": "子节点1", // 节点名称 "id": "11" // 节点id }, { "title": "子节点2", "id": "12" } ] }, { "title": "父节点2", "id": "2", "children": [ { "title": "子节点3", "id": "23" }, { "title": "子节点4", "id": "24" } ] } ] }
4.案列
1.实体类
package com.niyin.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 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 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; } @Override public String toString() { return "Permission [id=" + id + ", name=" + name + ", description=" + description + ", url=" + url + ", pid=" + pid + ", ismenu=" + ismenu + ", displayno=" + displayno + "]"; } public Permission() { // TODO Auto-generated constructor stub } }
2.dao方法
package com.niyin.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>>lst=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()+""); lst.add(vo); } return BuildTree.buildList(lst, "-1") ; } }
3.子实现类
package com.niyin.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; public class PermissonAction extends ActionSupport implements ModelDriver<Permission> { private Permission permission=new Permission(); private PermissionDao permissionDao = new PermissionDao(); public String menus(HttpServletRequest req, HttpServletResponse resp) throws Exception { List<TreeVo<Permission>> menus = permissionDao.menus(null, null); ResponseUtil.writeJson(resp, menus); System.out.println(menus); return super.execute(req, resp); } @Override public Permission getModel() { // TODO Auto-generated method stub return permission; } }
4.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file = "common/header.jsp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</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}/permisson.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>'; console.log(node.text); }); htmlStr+=' </dl>'; } htmlStr+='</li>'; console.log(n.text); }); $("#menu").html(htmlStr); element.render('menu'); } }); }); </script> </body> </html>
运行结果
一个树形就完成了