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可用)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM