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

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

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

部分源码修改截图:

调用例子:

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title></title>
  7. <meta name="renderer" content="webkit|ie-comp|ie-stand">
  8. <meta http-equiv="hg-UA-Compatible" content="IE=edge,chrome=1">
  9. <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
  10. <meta http-equiv="Cache-Control" content="no-siteapp" />
  11. <link rel="stylesheet" href="./css/font.css">
  12. <link rel="stylesheet" href="../lib/layui/css/layui.css" media="all">
  13. <link rel="stylesheet" href="./lib/admin/admin.css" media="all">
  14. <link rel="stylesheet" href="./lib/Scrollbar/jquery.scrollbar.css">
  15. <script type="text/javascript" src="./lib/admin/jquery-1.9.1.min.js"></script>
  16. <script type="text/javascript" src="./lib/Scrollbar/jquery.scrollBar.js"></script>
  17. <script type="text/javascript" src="./lib/layui/layui.js"></script>
  18. <script type="text/javascript" src="./lib/admin/admin.js"></script>
  19. <!--[if lt IE 9]>
  20. <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
  21. <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
  22. <![endif]-->
  23. <style>
  24. .demo-tree{
  25. width: 500px; height: 200px;
  26. }
  27. .demo-tree-box{
  28. width: 500px; height: 200px;border: 1px #eee solid;overflow-y: auto;
  29. }
  30. .demo-input-tree{
  31. height: auto;
  32. width: 100%;
  33. display: none;
  34. position: absolute;
  35. top: 100%;
  36. background-color: #fff;
  37. z-index: 100;
  38. max-height: 400px;
  39. }
  40. .layui-input{
  41. width: 500px;
  42. cursor: pointer;
  43. }
  44. </style>
  45. </head>
  46.  
  47. <body class="layui-body-content">
  48. <div class="layui-fluid">
  49. <div class="layui-card">
  50. <div class="layui-form layui-card-header layui-card-header-auto">
  51. <div class="layui-form-item">
  52. <label class="layui-form-label">部门:</label>
  53. <div class="layui-inline">
  54. <input type="text" name="dept" lay-verify="required" placeholder="请选择部门" autocomplete="off" class="layui-input" readonly="true">
  55. <div id="treeinputid" class="demo-input-tree demo-tree-box"></div>
  56. </div>
  57. <div class="layui-inline layui-show-xs-block">
  58. <button class="layui-btn layui-btn-lg layui-btn-normal" lay-submit lay-filter="sreach"><i
  59. class="layui-icon layui-icon-lg"></i></button>
  60. </div>
  61. </div>
  62. </div>
  63. <div class="layui-card-body">
  64. <div class="layui-card-header">
  65. <button class="layui-btn layui-btn-lg layui-btn-normal"
  66. onclick="getChecked()"><i
  67. class="layui-icon"></i>获取选中</button>
  68. <button class="layui-btn layui-btn-lg layui-btn-warm" onclick="setChecked()"><i
  69. class="layui-icon"></i>设置节点勾选</button>
  70. <button class="layui-btn layui-btn-lg layui-btn-danger" onclick="reload()"><i
  71. class="layui-icon"></i>实例重载</button>
  72. </div>
  73. <div class="demo-tree">
  74. <div id="treeid" class="demo-tree demo-tree-box"></div>
  75. </div>
  76. </div>
  77. </div>
  78. <div class="layui-floor">
  79. <blockquote class="layui-elem-quote layui-quote-nm">Copyright©2019-2020, 本系统由@一如既往,提供技术支持!
  80. </blockquote>
  81. </div>
  82. </div>
  83. </body>
  84. <script>
  85. //初始化
  86. layui.use(['tree'], function () {
  87. var tree = layui.tree;
  88. //treeid
  89. var inst1 = tree.render({
  90. elem: '#treeid',
  91. id: 'treeid', //定义索引
  92. showCheckbox: true, //是否显示复选框
  93. showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。
  94. accordion: false, //是否开启手风琴模式,默认 false
  95. onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
  96. isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
  97. data: [{
  98. id: 'hg-100',
  99. field: '1',
  100. level: '1',
  101. title: '父节点100',
  102. spread: true,
  103. children: [{
  104. id: 'hg-100101',
  105. field: '3',
  106. level: '2',
  107. title: '子节点100101',
  108. children: [{
  109. id: 'hg-100101101',
  110. field: '4',
  111. level: '3',
  112. title: '子节点100101101'
  113. }, {
  114. id: 'hg-100101102',
  115. field: '5',
  116. level: '3',
  117. title: '子节点100101102'
  118. }, {
  119. id: 'hg-100101103',
  120. field: '6',
  121. level: '3',
  122. title: '子节点100101103'
  123. }]
  124. }]
  125. }, {
  126. id: 'hg-200',
  127. field: '2',
  128. level: '1',
  129. title: '父节点200',
  130. lazy: true
  131. }],
  132. text: {
  133. defaultNodeName: '无数据',
  134. none: '加载数据失败!'
  135. },
  136. click: function (obj) {
  137. console.log(obj.data); //得到当前点击的节点数据
  138. console.log(obj.state); //得到当前节点的展开状态:open、close、normal
  139. console.log(obj.elem); //得到当前节点元素
  140. console.log(obj.data.children); //当前节点下是否有子节点
  141. },
  142. oncheck: function (obj) {
  143. console.log(obj.data); //得到当前点击的节点数据
  144. console.log(obj.checked); //得到当前节点的展开状态:open、close、normal
  145. console.log(obj.elem); //得到当前节点元素
  146. },
  147. spread: function (obj) {
  148. console.log(obj);
  149. if(obj.state=='open'){
  150. setTimeout(() => {
  151. tree.lazytree(inst1.config.id, obj.elem, getTreeJson(obj.data.id));
  152. }, 2000);
  153. }
  154. }
  155. });
  156.  
  157. //treeinput
  158. var inst2;
  159. $("[name='dept']").on("click",function (e) {
  160. e.stopPropagation();
  161. const deprt = this;
  162. if(!inst2){
  163. inst2 = tree.render({
  164. elem: '#treeinputid',
  165. id: 'treeinputid', //定义索引
  166. showCheckbox: true, //是否显示复选框
  167. showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。
  168. accordion: false, //是否开启手风琴模式,默认 false
  169. onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
  170. isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
  171. data: [{
  172. id: 'hg-100',
  173. field: '1',
  174. level: '1',
  175. title: '父节点100',
  176. spread: true,
  177. children: [{
  178. id: 'hg-100101',
  179. field: '3',
  180. level: '2',
  181. title: '子节点100101',
  182. children: [{
  183. id: 'hg-100101101',
  184. field: '4',
  185. level: '3',
  186. title: '子节点100101101'
  187. }, {
  188. id: 'hg-100101102',
  189. field: '5',
  190. level: '3',
  191. title: '子节点100101102'
  192. }, {
  193. id: 'hg-100101103',
  194. field: '6',
  195. level: '3',
  196. title: '子节点100101103'
  197. }]
  198. }]
  199. }, {
  200. id: 'hg-200',
  201. field: '2',
  202. level: '1',
  203. title: '父节点200',
  204. lazy: true
  205. }],
  206. text: {
  207. defaultNodeName: '无数据',
  208. none: '加载数据失败!'
  209. },
  210. click: function (obj) {
  211. console.log(obj.data); //得到当前点击的节点数据
  212. console.log(obj.state); //得到当前节点的展开状态:open、close、normal
  213. console.log(obj.elem); //得到当前节点元素
  214. console.log(obj.data.children); //当前节点下是否有子节点
  215. },
  216. oncheck: function (obj) {
  217. var checkData = tree.getChecked(inst2.config.id);
  218. var map = getmap(checkData);
  219. $(deprt).val(map.value.join(','));
  220. },
  221. spread: function (obj) {
  222. console.log(obj);
  223. if(obj.state=='open'){
  224. setTimeout(() => {
  225. tree.lazytree(inst2.config.id, obj.elem, getTreeJson(obj.data.id));
  226. }, 2000);
  227. }
  228. }
  229. });
  230. }
  231. $("#treeinputid").toggle();
  232. })
  233.  
  234. //监听表单提交事件
  235. hg.form.onsubmit('sreach', function (data) {
  236. $("#treeinputid").hide();
  237. var checkData = tree.getChecked(inst2.config.id);
  238. var map = getmap(checkData);
  239. var init = map.result;
  240. hg.msg(JSON.stringify(init));
  241. });
  242.  
  243. const getmap = (target, result = []) => {
  244. layui.each(target,(i,e)=>{
  245. e.id && result.push({id:e.id,title:e.title});
  246. e.children && getmap(e.children, result);
  247. });
  248. let titles = result.map(e=>{return e.title});
  249. return {value:titles,result:result};
  250. };
  251.  
  252. });
  253.  
  254. // 模拟后台返回数据
  255. function getTreeJson(id) {
  256. if (id === 'hg-200') {
  257. return [{
  258. id: 'hg-200101',
  259. level: '2',
  260. title: '子节点200101'
  261. }, {
  262. id: 'hg-200102',
  263. level: '2',
  264. title: '子节点200102',
  265. lazy: true
  266. }];
  267. }
  268. if (id === 'hg-200102') {
  269. return [{
  270. id: 'hg-200102101',
  271. level: '3',
  272. title: '子节点200102101'
  273. }, {
  274. id: 'hg-200102102',
  275. level: '3',
  276. title: '子节点200102102',
  277. lazy: true
  278. }];
  279. }
  280. if (id === 'hg-200102102') {
  281. return [{
  282. id: 'hg-200102102101',
  283. level: '4',
  284. title: '子节点200102102101'
  285. }, {
  286. id: 'hg-200102102102',
  287. level: '4',
  288. title: '子节点200102102102',
  289. }];
  290. }
  291. }
  292. //获得选中的节点
  293. function getChecked(){
  294. layui.use(['tree'], function () {
  295. var tree = layui.tree;
  296. var checkData = tree.getChecked('treeid');
  297. hg.msg(JSON.stringify(checkData));
  298. });
  299. }
  300. //设置节点勾选
  301. function setChecked(){
  302. layui.use(['tree'], function () {
  303. var tree = layui.tree;
  304. tree.setChecked('treeid', ['hg-100101101','hg-100101102']);
  305. });
  306. }
  307. //实例重载
  308. function reload(){
  309. layui.use(['tree'], function () {
  310. var tree = layui.tree;
  311. tree.reload('treeid', {
  312. });
  313. });
  314. }
  315.  
  316. </script>
  317.  
  318. </html>
  1. <script>
  2. //初始化
  3. layui.use(['tree'], function () {
  4. var tree = layui.tree;
  5. //treeid
  6. var inst1 = tree.render({
  7. elem: '#treeid',
  8. id: 'treeid', //定义索引
  9. showCheckbox: true, //是否显示复选框
  10. showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。
  11. accordion: false, //是否开启手风琴模式,默认 false
  12. onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
  13. isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
  14. data: [{
  15. id: 'hg-100',
  16. field: '1',
  17. level: '1',
  18. title: '父节点100',
  19. spread: true,
  20. children: [{
  21. id: 'hg-100101',
  22. field: '3',
  23. level: '2',
  24. title: '子节点100101',
  25. children: [{
  26. id: 'hg-100101101',
  27. field: '4',
  28. level: '3',
  29. title: '子节点100101101'
  30. }, {
  31. id: 'hg-100101102',
  32. field: '5',
  33. level: '3',
  34. title: '子节点100101102'
  35. }, {
  36. id: 'hg-100101103',
  37. field: '6',
  38. level: '3',
  39. title: '子节点100101103'
  40. }]
  41. }]
  42. }, {
  43. id: 'hg-200',
  44. field: '2',
  45. level: '1',
  46. title: '父节点200',
  47. lazy: true
  48. }],
  49. text: {
  50. defaultNodeName: '无数据',
  51. none: '加载数据失败!'
  52. },
  53. click: function (obj) {
  54. console.log(obj.data); //得到当前点击的节点数据
  55. console.log(obj.state); //得到当前节点的展开状态:open、close、normal
  56. console.log(obj.elem); //得到当前节点元素
  57. console.log(obj.data.children); //当前节点下是否有子节点
  58. },
  59. oncheck: function (obj) {
  60. console.log(obj.data); //得到当前点击的节点数据
  61. console.log(obj.checked); //得到当前节点的展开状态:open、close、normal
  62. console.log(obj.elem); //得到当前节点元素
  63. },
  64. spread: function (obj) {
  65. console.log(obj);
  66. if(obj.state=='open'){
  67. setTimeout(() => {
  68. tree.lazytree(inst1.config.id, obj.elem, getTreeJson(obj.data.id));
  69. }, 2000);
  70. }
  71. }
  72. });
  73.  
  74. //treeinput
  75. var inst2;
  76. $("[name='dept']").on("click",function (e) {
  77. e.stopPropagation();
  78. const deprt = this;
  79. if(!inst2){
  80. inst2 = tree.render({
  81. elem: '#treeinputid',
  82. id: 'treeinputid', //定义索引
  83. showCheckbox: true, //是否显示复选框
  84. showLine: true, //是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。
  85. accordion: false, //是否开启手风琴模式,默认 false
  86. onlyIconControl: false, //是否仅允许节点左侧图标控制展开收缩。默认 false
  87. isJump: false, //是否允许点击节点时弹出新窗口跳转。默认 false
  88. data: [{
  89. id: 'hg-100',
  90. field: '1',
  91. level: '1',
  92. title: '父节点100',
  93. spread: true,
  94. children: [{
  95. id: 'hg-100101',
  96. field: '3',
  97. level: '2',
  98. title: '子节点100101',
  99. children: [{
  100. id: 'hg-100101101',
  101. field: '4',
  102. level: '3',
  103. title: '子节点100101101'
  104. }, {
  105. id: 'hg-100101102',
  106. field: '5',
  107. level: '3',
  108. title: '子节点100101102'
  109. }, {
  110. id: 'hg-100101103',
  111. field: '6',
  112. level: '3',
  113. title: '子节点100101103'
  114. }]
  115. }]
  116. }, {
  117. id: 'hg-200',
  118. field: '2',
  119. level: '1',
  120. title: '父节点200',
  121. lazy: true
  122. }],
  123. text: {
  124. defaultNodeName: '无数据',
  125. none: '加载数据失败!'
  126. },
  127. click: function (obj) {
  128. console.log(obj.data); //得到当前点击的节点数据
  129. console.log(obj.state); //得到当前节点的展开状态:open、close、normal
  130. console.log(obj.elem); //得到当前节点元素
  131. console.log(obj.data.children); //当前节点下是否有子节点
  132. },
  133. oncheck: function (obj) {
  134. var checkData = tree.getChecked(inst2.config.id);
  135. var map = getmap(checkData);
  136. $(deprt).val(map.value.join(','));
  137. },
  138. spread: function (obj) {
  139. console.log(obj);
  140. if(obj.state=='open'){
  141. setTimeout(() => {
  142. tree.lazytree(inst2.config.id, obj.elem, getTreeJson(obj.data.id));
  143. }, 2000);
  144. }
  145. }
  146. });
  147. }
  148. $("#treeinputid").toggle();
  149. })
  150.  
  151. //监听表单提交事件
  152. hg.form.onsubmit('sreach', function (data) {
  153. $("#treeinputid").hide();
  154. var checkData = tree.getChecked(inst2.config.id);
  155. var map = getmap(checkData);
  156. var init = map.result;
  157. hg.msg(JSON.stringify(init));
  158. });
  159.  
  160. const getmap = (target, result = []) => {
  161. layui.each(target,(i,e)=>{
  162. e.id && result.push({id:e.id,title:e.title});
  163. e.children && getmap(e.children, result);
  164. });
  165. let titles = result.map(e=>{return e.title});
  166. return {value:titles,result:result};
  167. };
  168.  
  169. });
  170.  
  171. // 模拟后台返回数据
  172. function getTreeJson(id) {
  173. if (id === 'hg-200') {
  174. return [{
  175. id: 'hg-200101',
  176. level: '2',
  177. title: '子节点200101'
  178. }, {
  179. id: 'hg-200102',
  180. level: '2',
  181. title: '子节点200102',
  182. lazy: true
  183. }];
  184. }
  185. if (id === 'hg-200102') {
  186. return [{
  187. id: 'hg-200102101',
  188. level: '3',
  189. title: '子节点200102101'
  190. }, {
  191. id: 'hg-200102102',
  192. level: '3',
  193. title: '子节点200102102',
  194. lazy: true
  195. }];
  196. }
  197. if (id === 'hg-200102102') {
  198. return [{
  199. id: 'hg-200102102101',
  200. level: '4',
  201. title: '子节点200102102101'
  202. }, {
  203. id: 'hg-200102102102',
  204. level: '4',
  205. title: '子节点200102102102',
  206. }];
  207. }
  208. }
  209. //获得选中的节点
  210. function getChecked(){
  211. layui.use(['tree'], function () {
  212. var tree = layui.tree;
  213. var checkData = tree.getChecked('treeid');
  214. hg.msg(JSON.stringify(checkData));
  215. });
  216. }
  217. //设置节点勾选
  218. function setChecked(){
  219. layui.use(['tree'], function () {
  220. var tree = layui.tree;
  221. tree.setChecked('treeid', ['hg-100101101','hg-100101102']);
  222. });
  223. }
  224. //实例重载
  225. function reload(){
  226. layui.use(['tree'], function () {
  227. var tree = layui.tree;
  228. tree.reload('treeid', {
  229. });
  230. });
  231. }
  232.  
  233. </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. Intel和AMD的CPU性能对比图

    Intel和AMD的CPU性能对比图:

  2. .NET 收徒,带你走向架构师。

    最近感悟天命,偶有所得,故而打算收徒若干,以继吾之传承. 有缘者,可破瓶颈,走向架构师之峰,指日可待. 入门基本要求: 1.工作经验:1年或以上. 2.入门费用:10000元(RMB). 联系方式(联 ...

  3. strcmp函数和memcmp函数的用法区别及联系

    前言: C语言中有很多东西容易搞混,最近笔者就遇到了一个问题.这里做个记录.就是memcmp和strcmp两者的用法,这里做个对比: 功能对比: A memcmp: 函数原型: int memcmp( ...

  4. js 五种绑定彻底弄懂this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解

     壹 ❀ 引 可以说this与闭包.原型链一样,属于JavaScript开发中老生常谈的问题了,百度一搜,this相关的文章铺天盖地.可开发好几年,被几道this题安排明明白白的人应该不在少数(我就是 ...

  5. OLTP

    On-Line Transaction Processing,联机事务处理过程(OLTP),也称为面向交易的处理过程 其基本特征是前台接收的用户数据可以立即传送到计算中心进行处理,并在很短的时间内给出 ...

  6. Comet OJ - Contest #11 B题 usiness

    ###题目链接### 题目大意:一开始手上有 0 个节点,有 n 天抉择,m 种方案,在每天中可以选择任意种方案.任意次地花费 x 个节点(手上的节点数不能为负),使得在 n 天结束后,获得 y 个节 ...

  7. BearerToken之JWT的介绍

    Bearer认证 HTTP提供了一套标准的身份验证框架:服务器可以用来针对客户端的请求发送质询(challenge),客户端根据质询提供身份验证凭证.质询与应答的工作流程如下:服务器端向客户端返回40 ...

  8. 剑指offer笔记面试题1----赋值运算符函数

    题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数. class CMyString{ public: CMyString(char* pData = nullptr); CMyS ...

  9. Cesium 动态绘制点线面(附源码下载)

    我写的这个点线面绘制融入了增删改的功能.其中可以通过手动点击地图进行动态绘制线面,也支持通过给定坐标数组来进行线面的增加.绘制好的线面,可以点击进行修改:以上介绍了我的大概的要给操作,下面以面的构建来 ...

  10. 百度大脑UNIT3.0详解之语音语义一体化方案

    在电话客服场景里,用户和机器人交流的过程中,经常会出现沉默.打断机器人.噪声等情况,机器人在应对这些异常情况的时候,需要语音和语义理解技术进行处理,才能实现用户和机器人的流畅交谈.而这些能力的获取与应 ...