众所周知,layui.tree的树形控件,在渲染树节点时,需要后台准备好整个组织树的数据;如果组织树的数据量特别大,页面渲染就特别慢。最近在狐小E智慧办公平台中,展示企业部门树时,就遇到这种问题;当时产品要求,部门树渲染要特别快,同时某部门下新增/删除了一个子部门时,要动态刷新,实时呈现;然而layui.tree的原始机制是,必须重新加载整个树的数据再渲染,这样就会导致展开的节点全收缩回去,而不是刚好展开到该父部门位置;
这样就有2个问题亟需优化:
1)部门树数据量大时,渲染慢。
2)父部门如何动态刷新子部门,并且局部更新视图;
为了解决这2个问题,我们只好修改layui.tree源码,实现这种高大上的功能;废话不多说,直接上干货:
狐小E智慧办公后台使用的layui版本是v2.5.5,其他版本的layui源码可能有所不同,这点需注意。
解决方案
步骤1:源码修改
首先,在layui前端框架找到实现树组件的模块源码tree.js,如图所示:
1:打开源码,在树的主渲染方法 r.render前,添加上用于加载child节点的方法r.children,代码如下:
r.children = function (e, i, d) {
var a = l.that[e];
return a.children(i, d)
}
效果如下图:
2:找到b.prototype.tree方法,在此方法前,添加两个用于懒加载子节点的方法:b.prototype.children = function (n1, n2) {
var e = this;
e.setchildrendata(e.config.data, n1, n2);
},
b.prototype.setchildrendata = function (n0, n1, n2) {
var e = this;
var c = i('#' + e.config.id);
layui.each(n0, function (a, r) {
var b = c.find('div[data-id=' + r.id + ']').hasClass(C);
r.spread = b;
if (e.config.accordion === !0) { //手风琴模式
r.spread = !1;
var cs = c.find('div[data-id=' + n1 + ']').parents('.layui-tree-set');
cs.each(function () {
if (r.id === i(this).attr('data-id')) {
r.spread = !0;
}
});
}
if (r.id === n1) {
r.spread = !0;
if(!r.children){
r.children=[];
}
if (n2.length === 0) {
delete r.children;
}else{
//i.extend(!0, r.children, n2);
r.children = n2;
}
e.reload(e.config.id, e.config.data);
}
if (r.children) {
e.setchildrendata(r.children, n1, n2); //递归子节点
}
});
}
3:修改b.prototype.tree方法的代码,修改后代码如下【备注://TODO 部分标识的是layui原始代码】
b.prototype.tree = func