LayUi框架中树形组件tree官方还在持续完善中,目前最新版本为v2.5.5

官方树形组件目前还不支持懒加载方式,之前我修改一版是通过reload重载实例方法填充子节点数据方式,因为递归页面元素时存在效率问题,最终放弃升级。

本次重新star了官方最新tree.js源码,在其基础上扩展了子节点懒加载模式方法,data数据参数中增加了lazy: true,开启懒加载模式,需要配合spread事件使用。

部分源码修改截图:

调用例子:

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
<meta name="renderer" content="webkit|ie-comp|ie-stand">
<meta http-equiv="hg-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link rel="stylesheet" href="./css/font.css">
<link rel="stylesheet" href="../lib/layui/css/layui.css" media="all">
<link rel="stylesheet" href="./lib/admin/admin.css" media="all">
<link rel="stylesheet" href="./lib/Scrollbar/jquery.scrollbar.css">
<script type="text/javascript" src="./lib/admin/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="./lib/Scrollbar/jquery.scrollBar.js"></script>
<script type="text/javascript" src="./lib/layui/layui.js"></script>
<script type="text/javascript" src="./lib/admin/admin.js"></script>
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<style>
.demo-tree{
width: 500px; height: 200px;
}
.demo-tree-box{
width: 500px; height: 200px;border: 1px #eee solid;overflow-y: auto;
}
.demo-input-tree{
height: auto;
width: 100%;
display: none;
position: absolute;
top: 100%;
background-color: #fff;
z-index: 100;
max-height: 400px;
}
.layui-input{
width: 500px;
cursor: pointer;
}
</style>
</head> <body class="layui-body-content">
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-form layui-card-header layui-card-header-auto">
<div class="layui-form-item">
<label class="layui-form-label">部门:</label>
<div class="layui-inline">
<input type="text" name="dept" lay-verify="required" placeholder="请选择部门" autocomplete="off" class="layui-input" readonly="true">
<div id="treeinputid" class="demo-input-tree demo-tree-box"></div>
</div>
<div class="layui-inline layui-show-xs-block">
<button class="layui-btn layui-btn-lg layui-btn-normal" lay-submit lay-filter="sreach"><i
class="layui-icon layui-icon-lg"></i></button>
</div>
</div>
</div>
<div class="layui-card-body">
<div class="layui-card-header">
<button class="layui-btn layui-btn-lg layui-btn-normal"
onclick="getChecked()"><i
class="layui-icon"></i>获取选中</button>
<button class="layui-btn layui-btn-lg layui-btn-warm" onclick="setChecked()"><i
class="layui-icon"></i>设置节点勾选</button>
<button class="layui-btn layui-btn-lg layui-btn-danger" onclick="reload()"><i
class="layui-icon"></i>实例重载</button>
</div>
<div class="demo-tree">
<div id="treeid" class="demo-tree demo-tree-box"></div>
</div>
</div>
</div>
<div class="layui-floor">
<blockquote class="layui-elem-quote layui-quote-nm">Copyright©2019-2020, 本系统由@一如既往,提供技术支持!
</blockquote>
</div>
</div>
</body>
<script>
//初始化
layui.use(['tree'], function () {
var tree = layui.tree;
//treeid
var inst1 = tree.render({
elem: '#treeid',
id: 'treeid', //定义索引
showCheckbox: true, //是否显示复选框
showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。
accordion: false, //是否开启手风琴模式,默认 false
onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
data: [{
id: 'hg-100',
field: '1',
level: '1',
title: '父节点100',
spread: true,
children: [{
id: 'hg-100101',
field: '3',
level: '2',
title: '子节点100101',
children: [{
id: 'hg-100101101',
field: '4',
level: '3',
title: '子节点100101101'
}, {
id: 'hg-100101102',
field: '5',
level: '3',
title: '子节点100101102'
}, {
id: 'hg-100101103',
field: '6',
level: '3',
title: '子节点100101103'
}]
}]
}, {
id: 'hg-200',
field: '2',
level: '1',
title: '父节点200',
lazy: true
}],
text: {
defaultNodeName: '无数据',
none: '加载数据失败!'
},
click: function (obj) {
console.log(obj.data); //得到当前点击的节点数据
console.log(obj.state); //得到当前节点的展开状态:open、close、normal
console.log(obj.elem); //得到当前节点元素
console.log(obj.data.children); //当前节点下是否有子节点
},
oncheck: function (obj) {
console.log(obj.data); //得到当前点击的节点数据
console.log(obj.checked); //得到当前节点的展开状态:open、close、normal
console.log(obj.elem); //得到当前节点元素
},
spread: function (obj) {
console.log(obj);
if(obj.state=='open'){
setTimeout(() => {
tree.lazytree(inst1.config.id, obj.elem, getTreeJson(obj.data.id));
}, 2000);
}
}
}); //treeinput
var inst2;
$("[name='dept']").on("click",function (e) {
e.stopPropagation();
const deprt = this;
if(!inst2){
inst2 = tree.render({
elem: '#treeinputid',
id: 'treeinputid', //定义索引
showCheckbox: true, //是否显示复选框
showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。
accordion: false, //是否开启手风琴模式,默认 false
onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
data: [{
id: 'hg-100',
field: '1',
level: '1',
title: '父节点100',
spread: true,
children: [{
id: 'hg-100101',
field: '3',
level: '2',
title: '子节点100101',
children: [{
id: 'hg-100101101',
field: '4',
level: '3',
title: '子节点100101101'
}, {
id: 'hg-100101102',
field: '5',
level: '3',
title: '子节点100101102'
}, {
id: 'hg-100101103',
field: '6',
level: '3',
title: '子节点100101103'
}]
}]
}, {
id: 'hg-200',
field: '2',
level: '1',
title: '父节点200',
lazy: true
}],
text: {
defaultNodeName: '无数据',
none: '加载数据失败!'
},
click: function (obj) {
console.log(obj.data); //得到当前点击的节点数据
console.log(obj.state); //得到当前节点的展开状态:open、close、normal
console.log(obj.elem); //得到当前节点元素
console.log(obj.data.children); //当前节点下是否有子节点
},
oncheck: function (obj) {
var checkData = tree.getChecked(inst2.config.id);
var map = getmap(checkData);
$(deprt).val(map.value.join(','));
},
spread: function (obj) {
console.log(obj);
if(obj.state=='open'){
setTimeout(() => {
tree.lazytree(inst2.config.id, obj.elem, getTreeJson(obj.data.id));
}, 2000);
}
}
});
}
$("#treeinputid").toggle();
}) //监听表单提交事件
hg.form.onsubmit('sreach', function (data) {
$("#treeinputid").hide();
var checkData = tree.getChecked(inst2.config.id);
var map = getmap(checkData);
var init = map.result;
hg.msg(JSON.stringify(init));
}); const getmap = (target, result = []) => {
layui.each(target,(i,e)=>{
e.id && result.push({id:e.id,title:e.title});
e.children && getmap(e.children, result);
});
let titles = result.map(e=>{return e.title});
return {value:titles,result:result};
}; }); // 模拟后台返回数据
function getTreeJson(id) {
if (id === 'hg-200') {
return [{
id: 'hg-200101',
level: '2',
title: '子节点200101'
}, {
id: 'hg-200102',
level: '2',
title: '子节点200102',
lazy: true
}];
}
if (id === 'hg-200102') {
return [{
id: 'hg-200102101',
level: '3',
title: '子节点200102101'
}, {
id: 'hg-200102102',
level: '3',
title: '子节点200102102',
lazy: true
}];
}
if (id === 'hg-200102102') {
return [{
id: 'hg-200102102101',
level: '4',
title: '子节点200102102101'
}, {
id: 'hg-200102102102',
level: '4',
title: '子节点200102102102',
}];
}
}
//获得选中的节点
function getChecked(){
layui.use(['tree'], function () {
var tree = layui.tree;
var checkData = tree.getChecked('treeid');
hg.msg(JSON.stringify(checkData));
});
}
//设置节点勾选
function setChecked(){
layui.use(['tree'], function () {
var tree = layui.tree;
tree.setChecked('treeid', ['hg-100101101','hg-100101102']);
});
}
//实例重载
function reload(){
layui.use(['tree'], function () {
var tree = layui.tree;
tree.reload('treeid', {
});
});
} </script> </html>
<script>
//初始化
layui.use(['tree'], function () {
var tree = layui.tree;
//treeid
var inst1 = tree.render({
elem: '#treeid',
id: 'treeid', //定义索引
showCheckbox: true, //是否显示复选框
showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。
accordion: false, //是否开启手风琴模式,默认 false
onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
data: [{
id: 'hg-100',
field: '1',
level: '1',
title: '父节点100',
spread: true,
children: [{
id: 'hg-100101',
field: '3',
level: '2',
title: '子节点100101',
children: [{
id: 'hg-100101101',
field: '4',
level: '3',
title: '子节点100101101'
}, {
id: 'hg-100101102',
field: '5',
level: '3',
title: '子节点100101102'
}, {
id: 'hg-100101103',
field: '6',
level: '3',
title: '子节点100101103'
}]
}]
}, {
id: 'hg-200',
field: '2',
level: '1',
title: '父节点200',
lazy: true
}],
text: {
defaultNodeName: '无数据',
none: '加载数据失败!'
},
click: function (obj) {
console.log(obj.data); //得到当前点击的节点数据
console.log(obj.state); //得到当前节点的展开状态:open、close、normal
console.log(obj.elem); //得到当前节点元素
console.log(obj.data.children); //当前节点下是否有子节点
},
oncheck: function (obj) {
console.log(obj.data); //得到当前点击的节点数据
console.log(obj.checked); //得到当前节点的展开状态:open、close、normal
console.log(obj.elem); //得到当前节点元素
},
spread: function (obj) {
console.log(obj);
if(obj.state=='open'){
setTimeout(() => {
tree.lazytree(inst1.config.id, obj.elem, getTreeJson(obj.data.id));
}, 2000);
}
}
}); //treeinput
var inst2;
$("[name='dept']").on("click",function (e) {
e.stopPropagation();
const deprt = this;
if(!inst2){
inst2 = tree.render({
elem: '#treeinputid',
id: 'treeinputid', //定义索引
showCheckbox: true, //是否显示复选框
showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。
accordion: false, //是否开启手风琴模式,默认 false
onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
data: [{
id: 'hg-100',
field: '1',
level: '1',
title: '父节点100',
spread: true,
children: [{
id: 'hg-100101',
field: '3',
level: '2',
title: '子节点100101',
children: [{
id: 'hg-100101101',
field: '4',
level: '3',
title: '子节点100101101'
}, {
id: 'hg-100101102',
field: '5',
level: '3',
title: '子节点100101102'
}, {
id: 'hg-100101103',
field: '6',
level: '3',
title: '子节点100101103'
}]
}]
}, {
id: 'hg-200',
field: '2',
level: '1',
title: '父节点200',
lazy: true
}],
text: {
defaultNodeName: '无数据',
none: '加载数据失败!'
},
click: function (obj) {
console.log(obj.data); //得到当前点击的节点数据
console.log(obj.state); //得到当前节点的展开状态:open、close、normal
console.log(obj.elem); //得到当前节点元素
console.log(obj.data.children); //当前节点下是否有子节点
},
oncheck: function (obj) {
var checkData = tree.getChecked(inst2.config.id);
var map = getmap(checkData);
$(deprt).val(map.value.join(','));
},
spread: function (obj) {
console.log(obj);
if(obj.state=='open'){
setTimeout(() => {
tree.lazytree(inst2.config.id, obj.elem, getTreeJson(obj.data.id));
}, 2000);
}
}
});
}
$("#treeinputid").toggle();
}) //监听表单提交事件
hg.form.onsubmit('sreach', function (data) {
$("#treeinputid").hide();
var checkData = tree.getChecked(inst2.config.id);
var map = getmap(checkData);
var init = map.result;
hg.msg(JSON.stringify(init));
}); const getmap = (target, result = []) => {
layui.each(target,(i,e)=>{
e.id && result.push({id:e.id,title:e.title});
e.children && getmap(e.children, result);
});
let titles = result.map(e=>{return e.title});
return {value:titles,result:result};
}; }); // 模拟后台返回数据
function getTreeJson(id) {
if (id === 'hg-200') {
return [{
id: 'hg-200101',
level: '2',
title: '子节点200101'
}, {
id: 'hg-200102',
level: '2',
title: '子节点200102',
lazy: true
}];
}
if (id === 'hg-200102') {
return [{
id: 'hg-200102101',
level: '3',
title: '子节点200102101'
}, {
id: 'hg-200102102',
level: '3',
title: '子节点200102102',
lazy: true
}];
}
if (id === 'hg-200102102') {
return [{
id: 'hg-200102102101',
level: '4',
title: '子节点200102102101'
}, {
id: 'hg-200102102102',
level: '4',
title: '子节点200102102102',
}];
}
}
//获得选中的节点
function getChecked(){
layui.use(['tree'], function () {
var tree = layui.tree;
var checkData = tree.getChecked('treeid');
hg.msg(JSON.stringify(checkData));
});
}
//设置节点勾选
function setChecked(){
layui.use(['tree'], function () {
var tree = layui.tree;
tree.setChecked('treeid', ['hg-100101101','hg-100101102']);
});
}
//实例重载
function reload(){
layui.use(['tree'], function () {
var tree = layui.tree;
tree.reload('treeid', {
});
});
} </script>

 【HG-Layui-UI通用后台管理框架V1.0版】

下载地址:

https://www.cnblogs.com/han1982/p/12003454.html

tree.js 下载地址在回复区可见。(layui-v2.5.5版本替换tree.js可用)

LayUi 树形组件tree 实现懒加载模式,展开父节点时异步加载子节点数据的更多相关文章

  1. JQuery/JS插件 jsTree加载树,预先加载,初始化时加载前三级节点,当展开第三级节点时 就加载该节点下的所有子节点

    jsTree加载树, 初始化时 加载前三级节点, 当展开第三级节点时 就加载该节点下的所有子节点 html: <!DOCTYPE html> <html> <head&g ...

  2. 修复使用<code>XmlDocument</code>加载含有DOCTYPE的Xml时,加载后增加“[]”字符的错误

    C# LINQ TO XML - Remove “[]” characters from the DTD header http://stackoverflow.com/questions/12358 ...

  3. zTree设置异步加载后展开

    //不能直接配置展开属性 因为没有数据,需要添加回调函数,异步加载成功展开 callback: { onAsyncSuccess: zTreeOnAsyncSuccess } //异步加载成功回调函数 ...

  4. 【EasyUI学习-2】Easyui Tree的异步加载

    作者:ssslinppp       1. 摘要 2. tree的相关介绍 3. 异步加载tree数据,并实现tree的折叠展开 3.1 功能说明: 3.2 前台代码 3.3 后台代码 4. 其他 1 ...

  5. EasyUI之树形结构tree

    转自:https://blog.csdn.net/ya_1249463314/article/details/70305730 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...

  6. 多线程异步加载图片async_pictures

    异步加载图片 目标:在表格中异步加载网络图片 目的: 模拟 SDWebImage 基本功能实现 理解 SDWebImage 的底层实现机制 SDWebImage 是非常著名的网络图片处理框架,目前国内 ...

  7. ztree异步加载树节点

    参考文档:https://www.cnblogs.com/tenWood/p/8620708.html ztree api地址:http://www.treejs.cn/v3/api.php 说明:j ...

  8. [翻译]Bitmap的异步加载和缓存

    内容概述 [翻译]开发文档:android Bitmap的高效使用 本文内容来自开发文档"Traning > Displaying Bitmaps Efficiently", ...

  9. Jquery Ztree异步加载树

    1. 下载jquery的JS文件/ztree的CSS文件和JS文件 https://jquery.com/download/ https://gitee.com/zTree/zTree_v3/tree ...

随机推荐

  1. C#线程学习笔记四:线程同步

    本笔记摘抄自:https://www.cnblogs.com/zhili/archive/2012/07/21/ThreadsSynchronous.html,记录一下学习过程以备后续查用.     ...

  2. day 28-1 元类

    元类 元类的用途:自定义元类控制类的创建行为及类的实例化行为 Python 中一切皆为对象. 一切接对象,对象可以怎么用呢? 1.都可以被引用,x=obj 2.都可以当作函数的参数传入 3.都可以当作 ...

  3. mysql-5.7.21-winx64安装教程

    1 . 下载对用的版本信息 地址是:https://dev.mysql.com/downloads/mysql/ 2 . 解压到目录 D:\tools\mysql\mysql-5.7.21-winx6 ...

  4. Android Healthd电池服务分析

    healthd healthd是安卓4.4之后提出来的,监听来自kernel的电池事件,并向上传递电池数据给framework层的BatteryService.BatteryService计算电池电量 ...

  5. [AI开发]DeepStream开发填坑记录

    下面是在deepstream使用过程中碰到的一些坑: (1)Pipeline中的Sink如果需要编码存文件或者推rtmp的流,注意控制编码的参数,编码质量不要太高.否则可能Sink带不动,整个Pipe ...

  6. 利用keras自带影评数据集进行评价正面与否的二分类训练

    from keras.datasets import imdb from keras import layers from keras import models from keras import ...

  7. Java面向对象之继承(一)

    目录 Java面向对象之继承 引言 继承的特点 语法格式 父子类的关系 继承要点 重写父类方法 继承中的构造器 继承中的super关键字 ... Java面向对象之继承 继承是面向对象的第二大特征,是 ...

  8. 网站后台getshell

    phpmyadmin后台Getshell 获取 web 绝对路径 select @@basedir; 检测是否有写入权限 show global variables like 'secure%' ## ...

  9. JavaWeb 错误/异常时页面提示

    经常我们会遇到发生页面404错误,服务器 500 异常,如果默认方式处理,则是将异常捕获之后跳到 Tomcat 缺省的异常页面,如下图所示.

  10. Android开发之OkHttp介绍

    要论时下最火的网络请求框架,当属OkHttp了.自从Android4.4开始,google已经开始将源码中的HttpURLConnection替换为OkHttp,而在Android6.0之后的SDK中 ...