zoukankan      html  css  js  c++  java
  • LayUi 树形组件tree 实现懒加载模式,展开父节点时异步加载子节点数据

    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">&#xe615;</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">&#xe654;</i>获取选中</button>
                        <button class="layui-btn layui-btn-lg layui-btn-warm" onclick="setChecked()"><i
                                class="layui-icon">&#xe642;</i>设置节点勾选</button>
                        <button class="layui-btn layui-btn-lg layui-btn-danger" onclick="reload()"><i
                                class="layui-icon">&#xe640;</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>
    View Code
    <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可用)

  • 相关阅读:
    forEach方法的实现
    经典笔试题
    Js中的filter()方法
    arguments参数对象
    随机验证码实现
    DB2 字符串比较
    博客园那篇文章,怎么被“注入”的?
    DB2存储过程创建临时表,返回临时表集合
    Struts的一些关键词
    DB2使用笔记生成存储过程ID
  • 原文地址:https://www.cnblogs.com/han1982/p/11535627.html
Copyright © 2011-2022 走看看