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. AbstractMethodError: abstract method "androidx.databinding.ViewDataBinding androidx.databinding.DataBinderMapper.getDataBinder(androidx.databinding.DataBindingComponent, android.view.View, int)"

    混淆导致的数据绑定库错误 问题摘要 AbstractMethodError: abstract method "androidx.databinding.ViewDataBinding an ...

  2. 61-如何使用 Weave 网络?

    weave 是 Weaveworks 开发的容器网络解决方案.weave 创建的虚拟网络可以将部署在多个主机上的容器连接起来.对容器来说,weave 就像一个巨大的以太网交换机,所有容器都被接入这个交 ...

  3. 利用WPF生成Q币充值二维码——扫码登录篇

    一.前言 虽然腾讯官方不支持使用二维码充值Q币,但对于喜欢钻研的人来说这不是问题,本文利用WPF技术讲解从扫码登录到生成Q币充值二维码的一整套解决方案. 因为充值Q币需要先用QQ号登录官网.所以我们首 ...

  4. .NET 的未来:.NET 5

    前言 不知不觉中,.NET Framework 已经更新到 4.8,.NET Core 也更新到了 3.0 版本.那么 .NET 的未来怎么样呢? 计划 2019 年 Build 大会上,微软宣布下一 ...

  5. 龙芯(mips64)电脑安装NodeJS

    背景 龙芯是国产的cpu,采用是mips架构,就类似大家熟知的x86.arm. 最近在一台龙芯电脑(系统是中兴新支点,Linux)上调试前端应用(electron),于是就需要安装NodeJS. 但是 ...

  6. 打包vue文件,上传到服务器

    主要步骤: 1. npm run build生成dist文件夹 2. 将dist文件夹上传到服务器上 3. 服务器上配置nginx,访问路径指向dist文件夹下的index.html,这样当访问ngi ...

  7. Android studio 3.4 新建项目报错Error:unable to resolve dependency for app@。。。解决办法

    试过网上很多的例子,有的设置Go to `File->Settings->Build, Execution, Deployment->Gradle->Uncheck Offli ...

  8. TP随机从数据库中获取一条数据

    orderRaw('rand()'): /** * 随机获取一条商品信息 * @param [type] $condition * @param [type] $field * @param [typ ...

  9. 图像的相似度Hash算法

    Hash算法有三种,分别为平均哈希算法(aHash).感知哈希算法你(pHash)和差异哈哈希算法(dHash). 针对以上三种的Hash算法详解见博客园文章 https://www.cnblogs. ...

  10. Linux系统学习 十五、VSFTP服务—匿名用户访问(不推荐使用,不安全)

    匿名用户访问 基本配置: anonymous_enable          #允许匿名用户访问 anon_upload_enable       #允许匿名用户上传 anon_mkdir_write ...