本文详细解析 LayUI Tree 组件的实际应用,涵盖从引入样式、配置参数到后台数据交互的全过程。重点讲解如何通过递归处理 JSON 键名映射,实现树形数据的正确渲染。同时深入演示节点点击、编辑、删除及新增操作的回调处理,并结合 LayUI TreeSelect 实现上级部门选择,最后提供获取选中节点并转换为 JSON 字符串传给后台的完整解决方案。
树形结构在软件开发中应用广泛,例如部门组织架构管理、系统权限菜单配置等场景。采用树形结构展示层级关系,能够使界面逻辑更加清晰直观,便于用户理解和管理。
在近期开发的一个个人博客项目中,笔者使用了 LayUI 的树形组件,并基于此构建了一个小型案例。现将该案例的开发过程与核心代码整理分享,供参考。
先看一下显示的效果图

点击树节点右侧的操作图标,可展开对应部门的详细信息并进行编辑。系统支持自定义按钮以添加部门,同时也内置了标准的新增、修改和删除功能。此外,程序支持获取当前选中的节点数据,以便根据具体业务需求(如选中后自动保存)进行后续处理。
使用前,首先需要在项目中引入 LayUI 框架所需的 JavaScript 和 CSS 样式文件,确保组件正常加载。
案例对应的实体类Dept
@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() {
}
}在 LayUI 中渲染树形菜单,前端仅需提供一个指定的标签容器即可,无需复杂的 DOM 结构。
<div id="dept_tree">
</div>除了基础的树形展示,案例中还包含了其他辅助 UI 元素,例如右侧用于显示详情信息的区域、用于触发新增操作的按钮等,以完善用户体验。
完整代码如下
<style type="text/css">
#dept_main, #dept_particulars{
width: 48.5%;
display: inline-block;
vertical-align: top;
padding: 20px;
background: white;
box-sizing: border-box;
}
#dept_tree{
margin-top: 20px;
}
</style><div id="dept_main" style="margin-right: 2%;">
<fieldset class="layui-elem-field layui-field-title">
<legend>所有部门</legend>
</fieldset>
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon"></i>添加部门</button>
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">获取选中节点</button>
<div id="dept_tree">
</div>
</div>
<div id="dept_particulars">
<fieldset class="layui-elem-field layui-field-title">
<legend>部门详情</legend>
</fieldset>
<div id="dept_home">
<div class="layui-tree-emptyText">无数据</div>
</div>
</div>前端通过 JavaScript 请求后端数据并渲染页面。data 变量用于存储请求到的数据源。起初尝试直接传入请求链接,但发现无法正常工作,因此改为封装一个专门的方法来获取数据源。
layui.use(['tree', 'util'], function() {
var tree = layui.tree;
var util = layui.util;
tree.render({
elem: '#dept_tree',
data: getData(),
id: 'treeId',
showCheckbox: true, //是否显示复选框
onlyIconControl: true
});
});
function getData(){
var data = [];
$.ajax({
url: "dept/treeload", //后台数据请求地址
type: "post",
async:false,
success: function(resut){
data = resut;
}
});
return data;
}tree 组件提供了丰富的基础配置参数,开发者可根据具体业务需求进行相应设置。
| 参数选项 | 说明 | 类型 | 示例值 |
|---|---|---|---|
| elem | 指向容器选择器 | String/Object | - |
| data | 数据源 | Array | - |
| id | 设定实例唯一索引,用于基础方法传参使用。 | String | - |
| showCheckbox | 是否显示复选框 | Boolean | false |
| edit | 是否开启节点的操作图标。默认 false。
| Boolean/Array | ['update', 'del'] |
| accordion | 是否开启手风琴模式,默认 false | Boolean | false |
| onlyIconControl | 是否仅允许节点左侧图标控制展开收缩。默认 false(即点击节点本身也可控制)。若为 true,则只能通过节点左侧图标来展开收缩 | Boolean | false |
| isJump | 是否允许点击节点时弹出新窗口跳转。默认 false,若开启,需在节点数据中设定 link 参数(值为 url 格式) | Boolean | false |
| showLine | 是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。 | Boolean | true |
| text | 自定义各类默认文本,目前支持以下设定: text: { defaultNodeName: '未命名' //节点默认名称 ,none: '无数据' //数据为空时的提示文本 } | Object | - |
由于 LayUI tree 组件指定了 JSON 数据中特定字段的键名,若后台返回的数据键名与组件要求不一致,则需要进行映射处理。另一种方案是让实体类的属性名直接对应 tree 所需的 JSON 键名,以简化处理流程。
组件要求的 JSON 数据键名定义如下:
| 属性选项 | 说明 | 类型 | 示例值 |
|---|---|---|---|
| title | 节点标题 | String | 未命名 |
| id | 节点唯一索引,用于对指定节点进行各类操作 | String/Number | 任意唯一的字符或数字 |
| children | 子节点。支持设定选项同父节点 | Array | [{title: '子节点1', id: '111'}] |
| href | 点击节点弹出新窗口对应的 url。需开启 isJump 参数 | String | 任意 URL |
| spread | 节点是否初始展开,默认 false | Boolean | true |
| checked | 节点是否初始为选中状态(如果开启复选框的话),默认 false | Boolean | true |
| disabled | 节点是否为禁用状态。默认 false | Boolean | false |
以下是后端负责提供数据的方法实现。
@RequestMapping(value = "/treeload")
@ResponseBody
public Object treeload(){
Sort sort = Sort.by("idx");
List<Dept> dpet = deptService.findByParentIsNull(sort); //查找所有菜单
List<HashMap<String, Object>> result = new ArrayList<>(); //定义一个map处理json键名问题
return fun(dpet, result);
}
private Object fun(List<Dept> dpet, List<HashMap<String, Object>> result) {
for(Dept d : dpet){
HashMap<String, Object> map = new HashMap<>();
map.put("id", d.getId());
map.put("title", d.getName());
map.put("spread", true); //设置是否展开
List<HashMap<String, Object>> result1 = new ArrayList<>();
List<Dept> children = d.getChildren(); //下级菜单
//这里可以根据自己需求判断节点默认选中
/*if(m.getParent() != null || m.getChildren().size() == 0){
map.put("checked", true); //设置为选中状态
}*/
map.put("children", fun(children, result1));
result.add(map);
}
return result;
}由于本案例中新建的实体类字段名与 tree 组件指定的 JSON 键名不一致,因此使用了一个名为 fun 的递归方法进行处理。在递归过程中,可根据项目实际需求,通过条件判断来决定是否选中特定节点。
后端返回的 JSON 数据格式需符合 LayUI tree 组件的要求。

[
{
"children": [ //子节点
{
"children": [
{
"children": [],
"id": 30,
"title": "测试",
"spread": true
}, {
"children": [],
"id": 31,
"title": "开发",
"spread": true
}, {
"children": [
{
"children": [],
"id": 36,
"title": "测试节点",
"spread": true
}
],
"id": 32,
"title": "测试",
"spread": true
}
],
"id": 2,
"title": "技术部",
"spread": true
}, {
"children": [],
"id": 19,
"title": "财务部",
"spread": true
}
],
"id": 1, //节点id
"title": "某某公司", //节点名称
"spread": true
}, {
"children": [],
"id": 33,
"title": "测试",
"spread": true
}
]设置节点点击事件的回调方法,该代码需添加到加载数据的 tree.render 配置中。
click: function (obj) {
var id = obj.data.id;
$("#dept_home").load("dept/show?id="+id);
}当点击节点时,将请求到的详情页面内容加载到右侧的 div 容器中显示。此处涉及后端的数据查询方法。
@RequestMapping(value = "/show")
public void show(DeptForm form, ModelMap map) throws InstantiationException, IllegalAccessException {
Dept model = new Dept();
Integer id = form.getId();
Integer parentId = 0;
if(id!=null) {
model = deptService.findById(id);
parentId = model.getParent()==null?0:model.getParent().getId();
}
map.put("parentId", parentId);
map.put("model", model);
}DeptForm 类作为一个接收类,其字段定义与实体类保持一致。系统根据请求传递过来的 id,查询该条数据的详细信息,随后将当前部门的详情数据及父级节点 id(用于在下拉树 TreeSelect 中显示上级部门)传递给详情页面。
以下是 show.html 详情页面的完整代码实现。
<meta charset="UTF-8" />
<style type="text/css">
.myData .layui-form-item{
margin: 20px 100px 10px 45px;
}
.myData .layui-form-label{
width: 85px;
}
.layui-input-block {
margin-left: 120px;
}
</style>
<form class="layui-form myData" action="save" method="post" lay-filter="stuform">
<input type="hidden" name="id" data-th-value="${model.id}" />
<div class="layui-form-item">
<label class="layui-form-label">上级部门:</label>
<div class="layui-input-block">
<input type="text" name="parentId" id="tree" lay-filter="tree" class="layui-input" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">部门名称:</label>
<div class="layui-input-block">
<input type="text" name="name" lay-verify="required" th:value="${model.name}" class="layui-input" />
</div>
</div>
<div class="layui-form-item" >
<label class="layui-form-label">部门负责人:</label>
<div class="layui-input-block">
<input type="text" name="deptName" th:value="${model.deptName}" class="layui-input" />
</div>
</div>
<div class="layui-form-item" >
<label class="layui-form-label">电话:</label>
<div class="layui-input-block">
<input type="text" name="phone" th:value="${model.phone}" class="layui-input" />
</div>
</div>
<div class="layui-form-item" >
<label class="layui-form-label">编号:</label>
<div class="layui-input-block">
<input type="text" name="number" th:value="${model.number}" class="layui-input" />
</div>
</div>
<div class="layui-form-item" >
<label class="layui-form-label">排序:</label>
<div class="layui-input-block">
<input type="text" name="idx" value="0" th:value="${model.idx}" class="layui-input" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<button lay-submit class="layui-btn layui-btn-radius layui-btn-normal" lay-filter="btnSub">
<i class="layui-icon"></i>修改并保存
</button>
</div>
</div>
</form>
<script th:inline="javascript">
layui.use(["treeSelect", "form", "tree"], function () {
var form = layui.form;
var tree = layui.tree;
form.render('select');
var treeSelect = layui.treeSelect;
treeSelect.render({
// 选择器
elem: '#tree',
// 数据
data: 'dept/treeSelect?id='+[[${model.id==null ? 0 : model.id}]],
// 异步加载方式:get/post,默认get
type: 'post',
// 占位符
placeholder: '上级菜单',
// 是否开启搜索功能:true/false,默认false
search: true,
// 一些可定制的样式
style: {
folder: {
enable: true
},
line: {
enable: true
}
},
// 加载完成后的回调函数
success: function (d) {
// 选中节点,根据id筛选
treeSelect.checkNode('tree', [[${model.parent == null? parentId: model.parent.id}]]);
treeSelect.refresh('tree');
}
});
form.on('submit(btnSub)', function (data) {
$.post('dept/save', data.field, function (result) {
if (result.success) {
tree.reload('treeId', {data: getData()});
}
layer.msg(result.msg, {offset: 'rb'});
});
return false;
});
});
</script>上级部门的选择使用了 LayUI 的下拉树组件(TreeSelect)。关于下拉树的数据请求方法,可参考 LayUI 下拉树 TreeSelect 的使用文档。
@RequestMapping(value="/treeSelect")
@ResponseBody
public Object treeSelect(Integer id) {
Sort sort = Sort.by("idx");
Specification<Dept> spec = buildSpec1();
List<Dept> list = deptService.findAll(spec,sort);
return buildTree(list, id);
}
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());
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"));
rules.add(parent);
return cb.and(rules.toArray(new Predicate[rules.size()]));
}
};
return specification;
}上述配置最终呈现的界面效果如图所示。

以下是修改并保存数据到后台的方法。由于新增和修改功能共用一个接口,系统通过 id 是否存在来区分操作类型。
@Override
public Object save(DeptForm form) {
try {
Dept model = new Dept();
Integer id = form.getId();
if(id != null) {
model = deptService.findById(id);
}
//父级菜单id
Integer parentId = form.getParentId();
if(parentId == null) {
model.setParent(null);
}else {
model.setParent(new Dept(parentId));
}
BeanUtils.copyProperties(form, model,"id", "parent");
deptService.save(model);
return new AjaxResult("数据保存成功!");
} catch (Exception e) {
return new AjaxResult(false,"数据保存失败");
}
}设置节点操作图标(如新增、修改、删除)的回调,该代码需添加到加载数据的 tree.render 配置中。
edit: ['add', 'update', 'del'], //操作节点的图标
operate: function(obj){
var type = obj.type; //得到操作类型:add、edit、del
var data = obj.data; //得到当前节点的数据
var elem = obj.elem; //得到当前节点元素
var id = data.id;
var name = data.title;
if(type === 'add'){ //增加节点
$.post("dept/save", {parentId: id, name: "未命名"}, function (result) {
tree.reload('treeId', {data: getData()});
})
//返回 key 值
return ;
} else if(type === 'update'){ //修改节点
$.post("dept/update", {id: id, name: name}, function () {
tree.reload('treeId', {data: getData()});
})
} else if(type === 'del'){ //删除节点
$.post("dept/delete", {id: id}, function () {
tree.reload('treeId', {data: getData()});
});
};
}其中 operate 为操作节点时的回调方法,用于处理用户点击操作图标的行为。
obj.type 表示操作类型,包括 add(新增)、update(修改)和 del(删除)。obj.data 包含操作节点后的最新数据对象。
当执行新增节点操作后,前端向后台发送请求以添加该节点。save 方法与上述修改方法类似,区别在于传递的 id 为新建节点的父级节点 id。
执行修改节点操作时,前端同样向后台发送修改请求,并传递该对象的 id 以及修改后的数据作为参数。后端响应方法负责处理数据更新。
@RequestMapping(value = "/update")
@ResponseBody
public Object update(DeptForm form) {
try {
Dept model = deptService.findById(form.getId());
model.setName(form.getName());
deptService.save(model);
return new AjaxResult("数据保存成功!");
} catch (Exception e) {
return new AjaxResult(false,"数据保存失败");
}
}删除节点的操作逻辑类似,前端只需传递被删除节点的 id 即可。后端提供对应的删除请求处理方法。
@RequestMapping(value="/delete")
@ResponseBody
public Object delete(Integer id) {
try {
deptService.deleteById(id);
return new AjaxResult("数据删除成功");
} catch (Exception e) {
return new AjaxResult(false,"数据删除失败");
}
}除了节点自带的操作图标,还可以通过外部按钮来操作树形菜单。
在页面中定义两个按钮,分别为它们添加 lay-demo 属性并设置对应的属性值。前端 JavaScript 通过监听该属性值,绑定相应的点击事件。
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon"></i>添加部门</button>
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">获取选中节点</button>以下是绑定“添加部门”和“获取选中节点”按钮点击事件的具体 JavaScript 代码。
util.event('lay-demo', {
addDept: function(othis){
$.get('dept/edit', function(data) {
layer.open({
type: 1,
title: '新增',
area: ['530px'],
content: data,
btn: ['提交', '退出'],
yes: function () {
},
success: function (layero, index) {
layui.use('form', function () {
var form = layui.form;
layero.addClass('layui-form');
var submitBtn = layero.find('.layui-layer-btn0');
submitBtn.attr('lay-filter', 'formVerify').attr('lay-submit', '');
layero.keydown(function (e) {
if (e.keyCode == 13) {
submitBtn.click();
}
});
form.on('submit(formVerify)', function (data) {
$.post('dept/save', data.field, function (result) {
if (result.success) {
layer.close(index);
tree.reload('treeId', {data: getData()});
}
layer.msg(result.msg, {offset: 'rb'});
});
return false;
});
});
}
})
})
},
gain: function () {
var checkData = tree.getChecked('treeId');
var str = JSON.stringify(checkData);
$.post('dept/checkedGain', {data: str}, function () {
});
layer.alert(JSON.stringify(checkData), {shade:0});
}
});点击“添加部门”按钮时,前端先发送请求到后台,并跳转至 edit 新增页面。edit.html 新增页面的代码与之前的 show.html 显示部门详情页面类似。上级部门同样使用 LayUI 下拉树组件显示,其数据请求方法与详情页面中的下拉树请求方法一致。新增后的保存逻辑也与前述保存方法相同。关于 LayUI 下拉树 TreeSelect 的具体使用,可参考相关文档。
以下是后端接收请求并跳转至 edit 页面的方法代码。
@RequestMapping(value = "/edit")
public void edit(){
}edit.html 页面的完整代码如下所示。
<meta charset="UTF-8" />
<style type="text/css">
.myData .layui-form-item{
margin: 20px 100px 10px 45px;
}
.myData .layui-form-label{
width: 85px;
}
.layui-input-block {
margin-left: 120px;
}
</style>
<form class="layui-form myData" action="save" method="post" lay-filter="stuform">
<div class="layui-form-item">
<label class="layui-form-label">上级部门:</label>
<div class="layui-input-block">
<input type="text" name="parentId" id="tree2" lay-filter="tree2" class="layui-input" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">部门名称:</label>
<div class="layui-input-block">
<input type="text" name="name" lay-verify="required" class="layui-input" />
</div>
</div>
<div class="layui-form-item" >
<label class="layui-form-label">部门负责人:</label>
<div class="layui-input-block">
<input type="text" name="deptName" class="layui-input" />
</div>
</div>
<div class="layui-form-item" >
<label class="layui-form-label">电话:</label>
<div class="layui-input-block">
<input type="text" name="phone" class="layui-input" />
</div>
</div>
<div class="layui-form-item" >
<label class="layui-form-label">编号:</label>
<div class="layui-input-block">
<input type="text" name="number" class="layui-input" />
</div>
</div>
<div class="layui-form-item" >
<label class="layui-form-label">排序:</label>
<div class="layui-input-block">
<input type="text" name="idx" value="0" class="layui-input" />
</div>
</div>
</form>
<script th:inline="javascript">
layui.use(["treeSelect", "form"], function () {
var form = layui.form;
form.render('select');
var treeSelect = layui.treeSelect;
treeSelect.render({
// 选择器
elem: '#tree2',
// 数据
data: 'dept/treeSelect',
// 异步加载方式:get/post,默认get
type: 'post',
// 占位符
placeholder: '上级菜单',
// 是否开启搜索功能:true/false,默认false
search: true,
// 一些可定制的样式
style: {
folder: {
enable: true
},
line: {
enable: true
}
},
// 加载完成后的回调函数
success: function (d) {
}
});
});
</script>上述代码运行后的页面效果如图所示。

点击“获取选中节点”按钮时,若项目要求保存数据,则需要获取选中节点的数据。此处可获取选中节点的数据,并将其作为参数传递到后台。传递到后台的数据是一个 JSON 字符串,需要进行转换处理。这里推荐两个常用的 JSON 转换工具:net.sf.json.JSONObject 和 Alibaba Fastjson。本案例使用的是 Alibaba Fastjson,需在项目中引入相应的依赖。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>为了便于输出和处理,新建了一个与 tree JSON 数据键名一致的工具类 DeptTree,具体代码如下。
import java.util.ArrayList;
import java.util.List;
public class DeptTree {
private Integer id;
private String title;
private boolean checked;
private boolean spread;
private List<DeptTree> children = new ArrayList<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<DeptTree> getChildren() {
return children;
}
public void setChildren(List<DeptTree> children) {
this.children = children;
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public boolean isSpread() {
return spread;
}
public void setSpread(boolean spread) {
this.spread = spread;
}
}后端接收到前端传递过来的 JSON 数据字符串后,将其转换并输出结果。
@RequestMapping(value = "/checkedGain")
@ResponseBody
public void checkedGain(String data){
List<DeptTree> array2 = JSONArray.parseArray(data, DeptTree.class);
treeData(array2);
}
//递归输出选中数据
private void treeData(List<DeptTree> array2) {
for (DeptTree tree: array2){
System.out.println(tree.getTitle()+"==="+tree.getId());
if(tree.getChildren() != null){
treeData(tree.getChildren());
}
}
}选中节点后,点击“获取选中节点数据”按钮,前端将选中数据发送至后台。

后端对应方法接收数据,进行转换后输出处理结果。

获取到数据后,后续的保存逻辑便变得简单直接。
后端相关方法的代码已在上述部分展示,页面全部代码如下。
<style type="text/css">
#dept_main, #dept_particulars{
width: 48.5%;
display: inline-block;
vertical-align: top;
padding: 20px;
background: white;
box-sizing: border-box;
}
#dept_tree{
margin-top: 20px;
}
</style>
<div id="dept_main" style="margin-right: 2%;">
<fieldset class="layui-elem-field layui-field-title">
<legend>所有部门</legend>
</fieldset>
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="addDept"><i class="layui-icon"></i>添加部门</button>
<button class="layui-btn layui-btn-sm layui-btn-radius layui-btn-normal" lay-demo="gain">获取选中节点</button>
<div id="dept_tree">
</div>
</div>
<div id="dept_particulars">
<fieldset class="layui-elem-field layui-field-title">
<legend>部门详情</legend>
</fieldset>
<div id="dept_home">
<div class="layui-tree-emptyText">无数据</div>
</div>
</div>
<script type="text/javascript">
layui.use(['tree', 'util', 'layer'], function() {
var tree = layui.tree;
var util = layui.util;
var layer = layui.layer;
tree.render({
elem: '#dept_tree',
data: getData(),
id: 'treeId',
showCheckbox: true, //时候显示复选框
onlyIconControl: true,
edit: ['add', 'update', 'del'], //操作节点的图标
click: function (obj) {
var id = obj.data.id;
$("#dept_home").load("dept/show?id="+id);
},
operate: function(obj){
var type = obj.type; //得到操作类型:add、edit、del
var data = obj.data; //得到当前节点的数据
var elem = obj.elem; //得到当前节点元素
var id = data.id;
var name = data.title;
if(type === 'add'){ //增加节点
$.post("dept/save", {parentId: id, name: "未命名"}, function (result) {
tree.reload('treeId', {data: getData()});
})
//返回 key 值
return ;
} else if(type === 'update'){ //修改节点
$.post("dept/update", {id: id, name: name}, function () {
tree.reload('treeId', {data: getData()});
})
} else if(type === 'del'){ //删除节点
$.post("dept/delete", {id: id}, function () {
tree.reload('treeId', {data: getData()});
});
};
}
});
util.event('lay-demo', {
addDept: function(othis){
$.get('dept/edit', function(data) {
layer.open({
type: 1,
title: '新增',
area: ['530px'],
content: data,
btn: ['提交', '退出'],
yes: function () {
},
success: function (layero, index) {
layui.use('form', function () {
var form = layui.form;
layero.addClass('layui-form');
var submitBtn = layero.find('.layui-layer-btn0');
submitBtn.attr('lay-filter', 'formVerify').attr('lay-submit', '');
layero.keydown(function (e) {
if (e.keyCode == 13) {
submitBtn.click();
}
});
form.on('submit(formVerify)', function (data) {
$.post('dept/save', data.field, function (result) {
if (result.success) {
layer.close(index);
tree.reload('treeId', {data: getData()});
}
layer.msg(result.msg, {offset: 'rb'});
});
return false;
});
});
}
})
})
},
gain: function () {
var checkData = tree.getChecked('treeId');
var str = JSON.stringify(checkData);
$.post('dept/checkedGain', {data: str}, function () {
});
layer.alert(JSON.stringify(checkData), {shade:0});
}
});
});
function getData(){
var data = [];
$.ajax({
url: "dept/treeload", //后台数据请求地址
type: "post",
async:false,
success: function(resut){
data = resut;
}
});
return data;
}
</script>以上为个人开发经验的总结,希望能为大家提供有益的参考。也希望大家多多支持本站。