效果是這樣的。主要是結合項目完成效果。這裏先創建一個實體類:
@Data
public class ATree extends TreeNode{
private String name;
}
接下來是父類:
@Data
public class TreeNode {
protected int id;
protected int parentId;
protected List<TreeNode> children = new ArrayList<TreeNode>();
public void add(TreeNode node) {
children.add(node);
}
}
基石搭建好了,下面是使用,那麼使用時有一個工具類:
import lombok.experimental.UtilityClass;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
@UtilityClass
public class TreeUtil {
/**
* 兩層循環實現建樹
*
* @param treeNodes 傳入的樹節點列表
* @return
*/
public <T extends TreeNode> List<T> buildByLoop(List<T> treeNodes, Object root) {
List<T> trees = new ArrayList<>();
for (T treeNode : treeNodes) {
if (root.equals(treeNode.getParentId())) {
trees.add(treeNode);
}
for (T it : treeNodes) {
if (it.getParentId() == treeNode.getId()) {
if (treeNode.getChildren() == null) {
treeNode.setChildren(new ArrayList<>());
}
treeNode.add(it);
}
}
}
return trees;
}
/**
* 使用遞歸方法建樹
*
* @param treeNodes
* @return
*/
public <T extends TreeNode> List<T> buildByRecursive(List<T> treeNodes, Object root) {
List<T> trees = new ArrayList<T>();
for (T treeNode : treeNodes) {
if (root.equals(treeNode.getParentId())) {
trees.add(findChildren(treeNode, treeNodes));
}
}
return trees;
}
/**
* 遞歸查找子節點
*
* @param treeNodes
* @return
*/
public <T extends TreeNode> T findChildren(T treeNode, List<T> treeNodes) {
for (T it : treeNodes) {
if (treeNode.getId() == it.getParentId()) {
if (treeNode.getChildren() == null) {
treeNode.setChildren(new ArrayList<>());
}
treeNode.add(findChildren(it, treeNodes));
}
}
return treeNode;
}
}
工具類建好以後,寫接口請求數據
這裏直接上service層的代碼,其他的只是單純的基本方法:
@Override
public String getLayuiList() {
List<ATree> propertyTree = this.getTree(要查詢的樹形結構數據列表);
return JsonUtils.toJson(propertyTree);
}
/**
*屬性結構
* @param list
* @return
*/
private List<ATree> getTree(List<實體類> list){
List<ATree> treeList = list.stream()
.filter(pro -> !pro.屬性().equals(pro.屬性()))
.map(pro -> {
ATree node = new ATree();
node.setId(Integer.parseInt(pro.getCode()));
node.setParentId(Integer.parseInt(pro.getPcode()));
node.setName(pro.getName());
return node;
}).collect(Collectors.toList());
return TreeUtil.buildByLoop(treeList, 0);
}
}
以上是最主要的方法,這裏用的表結構裏是有父子節點的表結構。
注:後臺返回的數據是list,然後轉成了json型的string,獲取的數據就是layui中的nodes裏的數據。
因爲用的不是前後端分離的,所以這裏直接賦值nodes
下面是頁面:
<div class="layui-form-item">
<label class="layui-form-label" style="width: 200px">分類</label>
<div class="layui-input-inline">
<div class="layui-unselect layui-form-select downpanel" >
<div class="layui-select-title" >
<span class="layui-input layui-unselect" id="treeclass">選擇</span>
<input type="hidden" id="grainProperty" name="grainProperty" lay-filter="couponType" layVerify="required" contentStyle="margin-right: 10%"/>
<i class="layui-edge"></i>
</div>
<dl class="layui-anim layui-anim-upbit">
<dd>
<ul id="classtree"></ul>
</dd>
</dl>
</div>
</div>
//以上是部分數據,可能有些樣式會不一樣的,具體再自己解決吧
<script>
layui.use(['tree', 'layer'], function(){
var layer = layui.layer
,$ = layui.jquery;
layui.tree({
elem: '#classtree' //指定元素
,click: function(node){ //點擊節點回調
var $select = $($(this)[0].elem).parents(".layui-form-select");
$select.removeClass("layui-form-selected").find(".layui-select-title span").html(node.name).end().find("input:hidden[name='grainProperty']").val(node.id);
}
,nodes: ${propertyList}//這裏是前臺直接返回的固定數據
});
$(".downpanel").on("click", ".layui-select-title", function (e) {
$(".layui-form-select").not($(this).parents(".layui-form-select")).removeClass("layui-form-selected");
$(this).parents(".downpanel").toggleClass("layui-form-selected");
layui.stope(e);
}).on("click", "dl i", function (e) {
layui.stope(e);
});
$(document).on("click", function (e) {
$(".layui-form-select").removeClass("layui-form-selected");
});
});
</script>
具體的要具體使用,這裏在我使用的項目中還是可以使用的。