树形结构在实际开发中是很长用的一种结构。最近写了一个LayUI的小案例,其中用到了TreeSelect,这里整理一下。
TreeSelect官网地址:https://fly.layui.com/extend/treeSelect/
显示效果图
因为TreeSelect不是LayUI官方开发的,而是第三方基于LayUI开发的,所以需要先用Layui引入一下文件。
之后页面只需要引入LayUI的CSS和JS就可以了。
页面给一个标签,用于显示TreeSelect下拉树选中的内容值,获取选中值时,直接获取标签值,就是选中的内容值。
<input type="text" name="parentId" id="tree2" lay-filter="tree2" class="layui-input" />
JS渲染样式代码
<script type="text/javascript"> layui.use(["treeSelect", "form", "tree"], function () { var form = layui.form; var tree = layui.tree; var treeSelect = layui.treeSelect; treeSelect.render({ // 选择器 elem: '#tree', // 异步获取下拉树需要显示的数据 data: 'dept/treeSelect', // 异步加载方式:get/post,默认get type: 'post', // 占位符 placeholder: '上级菜单', // 是否开启搜索功能:true/false,默认false search: true, // 一些可定制的样式 style: { folder: { enable: true }, line: { enable: true } }, // 点击节点回调 click: function(d){ //console.log(d); }, // 加载完成后的回调函数 success: function (d) { //console.log(d); // 选中节点,根据id筛选,一般修改时会有默认选中状态,可以在这里设置 //treeSelect.checkNode('tree', 2); //console.log($('#tree').val()); // 获取zTree对象,可以调用zTree方法 //var treeObj = treeSelect.zTree('tree'); // console.log(treeObj); // 刷新树结构 //treeSelect.refresh('tree'); } }); }); </script>
后台响应加载下拉树数据方法(有详细注释)
@RequestMapping(value="/treeSelect") @ResponseBody //这里写的,新增和修改数据请求都是同一个方法,如果是修改会传递一个修改对象的id public Object treeSelect(Integer id) { Sort sort = Sort.by("idx"); //排序 Specification<Dept> spec = buildSpec1(); //查询条件,查询父节点为null的元素 List<Dept> list = deptService.findAll(spec,sort); //查询,Dept为实体类 return buildTree(list, id); //转换为treeSelect指定的JSON数据格式方法 } private Object buildTree(List<Dept> list, Integer id) { List<HashMap<String, Object>> result=new ArrayList<>(); for (Dept dept : list) { if(dept.getId() != id) { //判断如果是修改的话,修改的节点及下级节点不显示,也就不加载 HashMap<String, Object> node=new HashMap<>(); node.put("id", dept.getId()); //节点id node.put("name",dept.getName()); //节点数据名称 node.put("open", false); //是否展开 node.put("checked", false); //是否选中,前台也可以设置是否选中 if(dept.getChildren().size() != 0) { //如果下级节点不为空, node.put("children",buildTree(dept.getChildren(), id)); //递归加载下级节点 } result.add(node); } } return result; } public Specification<Dept> buildSpec1() { Specification<Dept> specification = new Specification<Dept>() { private static final long serialVersionUID = 1L; @Override public Predicate toPredicate(Root<Dept> root, CriteriaQuery<?> query, CriteriaBuilder cb) { HashSet<Predicate> rules=new HashSet<>(); Predicate parent = cb.isNull(root.get("parent")); //查询父节点为null的元素 rules.add(parent); return cb.and(rules.toArray(new Predicate[rules.size()])); } }; return specification; }
Dept实体类代码
import com.fasterxml.jackson.annotation.JsonIgnore; import org.springframework.data.annotation.CreatedBy; import javax.persistence.*; import java.util.ArrayList; import java.util.List; @Entity public class Dept { private Integer id; private String name; //部门名称 private String deptName; //部门负责人 private String phone; //电话号 private String number; //编号 private double idx; //排序 @JsonIgnore private Dept parent; @JsonIgnore private List<Dept> children = new ArrayList<>(); @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public double getIdx() { return idx; } public void setIdx(double idx) { this.idx = idx; } @ManyToOne @CreatedBy public Dept getParent() { return parent; } public void setParent(Dept parent) { this.parent = parent; } @OneToMany(cascade=CascadeType.ALL,mappedBy="parent") @OrderBy(value="idx") public List<Dept> getChildren() { return children; } public void setChildren(List<Dept> children) { this.children = children; } public Dept(Integer id, String name, String deptName, String phone, String number, double idx, Dept parent, List<Dept> children) { this.id = id; this.name = name; this.deptName = deptName; this.phone = phone; this.number = number; this.idx = idx; this.parent = parent; this.children = children; } public Dept(Integer id) { this.id = id; } public Dept() { } }
这里后台持久层是使用的Spring-Data-Jpa,如果你是用的其他持久层框架,只要返回的JSON数据格式一样就可以了。
JSON数据格式
JSON数据
[ { "children": [ //下级节点 { "children": [ { "name": "测试", "checked": false, "id": 30, "open": false }, { "name": "开发", "checked": false, "id": 31, "open": false }, { "children": [ { "name": "测试节点", "checked": false, "id": 36, "open": false } ], "name": "测试", "checked": false, "id": 32, "open": false } ], "name": "技术部", "checked": false, "id": 2, "open": false }, { "name": "财务部", "checked": false, "id": 19, "open": false } ], "name": "某某公司", //节点内容 "checked": false, //是否选中 "id": 1, //id "open": false //是否展开 }, { "name": "测试", "checked": false, "id": 33, "open": false } ]
以上为个人经验,希望能给大家一个参考,也希望大家多多支持阿兔在线工具。