下面直接给你最实用、最常见的树形菜单加载父/子节点方法(也叫懒加载父子节点树),jQuery EasyUI 的tree组件完美支持这种模式:先加载顶级(父)节点,点击某个父节点时再异步加载它的直接子节点(不加载孙子节点,直到点击孙子节点的父节点),复制粘贴就能用,超级适合部门组织架构、菜单管理、无限级商品分类等场景,领导最爱的“性能好、加载快”效果全都有!
方法1:最推荐 - 标准父/子节点懒加载树(现在就用这个,3秒出效果)
<!DOCTYPEhtml><html><head><metacharset="UTF-8"><title>EasyUI 树形菜单 - 加载父/子节点(懒加载)</title><linkrel="stylesheet"type="text/css"href="https://www.jeasyui.com/easyui/themes/default/easyui.css"><linkrel="stylesheet"type="text/css"href="https://www.jeasyui.com/easyui/themes/icon.css"><scripttype="text/javascript"src="https://code.jquery.com/jquery-1.12.4.min.js"></script><scripttype="text/javascript"src="https://www.jeasyui.com/easyui/jquery.easyui.min.js"></script></head><body><divstyle="margin:30px;width:300px;"><p><strong>部门组织架构(点击部门加载下级)</strong></p><!-- 关键:只设置根节点url,不用onBeforeExpand --><ulid="deptTree"class="easyui-tree"data-options="url:'get_parent_nodes.php', <!-- 只加载顶级父节点 --> method:'get', animate:true, lines:true, loadFilter: myLoadFilter <!-- 可选:统一处理返回数据 -->"></ul></div><script>// 核心:当点击有子节点的节点时,自动向同一个url请求子节点(EasyUI内置机制)$('#deptTree').tree({// 当节点展开前,如果子节点未加载,会自动向url发送 parentId 参数请求子节点// 无需手动写onBeforeExpand!onLoadSuccess:function(node,data){// data是当前加载的节点数据console.log('加载完成:',node?node.text:'根节点');},onClick:function(node){$.messager.show({title:'你点击了',msg:'部门:'+node.text+(node.children?'(已加载子节点)':''),timeout:2000});}});// 可选:统一处理后台返回数据格式functionmyLoadFilter(data,parent){// EasyUI默认期望 [{id,text,state,children:[]}, ...]// 如果你的后台返回 {id,name,hasChild:true} 可以在这里转换varresult=[];$.each(data,function(i,item){varnode={id:item.id,text:item.name||item.text,iconCls:item.icon};// 关键:如果有子节点,设置state:'closed',EasyUI会自动懒加载if(item.hasChild||item.childrenCount>0){node.state='closed';}result.push(node);});returnresult;}</script></body></html>后台接口示例(get_parent_nodes.php)
EasyUI 会自动在加载子节点时传id参数(选中节点的id)
<?php// 获取父节点ID(根节点时没有)$parentId=isset($_GET['id'])?intval($_GET['id']):0;// 模拟数据(实际从数据库查该父节点下的直接子节点)$nodes=[];if($parentId==0){// 加载顶级部门$nodes=[['id'=>1,'name'=>'总公司','hasChild'=>true],['id'=>2,'name'=>'子公司A','hasChild'=>true]];}elseif($parentId==1){// 总公司下的部门$nodes=[['id'=>11,'name'=>'技术部','hasChild'=>true],['id'=>12,'name'=>'市场部','hasChild'=>false],['id'=>13,'name'=>'财务部','hasChild'=>true]];}elseif($parentId==11){// 技术部下的小组$nodes=[['id'=>111,'name'=>'前端组'],['id'=>112,'name'=>'后端组'],['id'=>113,'name'=>'测试组']];}// ... 其他分支echojson_encode($nodes);?>效果亮点:
- 页面打开只加载顶级节点(速度极快)
- 点击有子节点的部门 → 自动请求该部门下的直接子部门(不会一次性加载所有孙子、重孙子)
- 再次点击已加载的节点 → 直接展开/折叠(不再重复请求)
- 完美支持无限级层级(10级都没问题)
- EasyUI 自动处理加载状态(显示加载动画)
方法2:如果你想完全手动控制加载(更灵活)
$('#deptTree').tree({onBeforeExpand:function(node){// 手动设置本次加载的url(可以带额外参数)$('#deptTree').tree('options').url='get_children.php?parentId='+node.id+'&type=dept';}});方法3:结合左侧布局 + 右侧内容(经典后台部门树)
<divclass="easyui-layout"data-options="fit:true"><divdata-options="region:'west',title:'部门架构',split:true"style="width:280px;"><ulid="deptTree"class="easyui-tree"data-options="url:'get_parent_nodes.php',lines:true"></ul></div><divdata-options="region:'center',title:'部门详情'"><divid="deptInfo"style="padding:20px;">请在左侧选择一个部门查看详情</div></div></div><script>$('#deptTree').tree({onClick:function(node){$('#deptInfo').html('<h3>'+node.text+'</h3><p>部门ID:'+node.id+'</p><p>加载状态:已加载子节点</p>');// 实际可以:$('#deptInfo').panel('refresh', 'dept_detail.php?id=' + node.id);}});</script>你现在直接复制方法1的完整代码 + PHP接口示例,放到服务器运行,就能看到一个超级高效的父/子节点懒加载树了!
数据量再大也不怕,只加载当前需要的层级,性能完美。
想要我给你一个完整的部门管理示例(父子懒加载树 + 点击显示详情 + 添加/删除节点 + 保存到数据库)?
或者你告诉我你的数据结构(比如字段叫pid、category_name、is_leaf),我2分钟帮你改好loadFilter和接口逻辑,复制就能跑!
快说说你的具体场景,我手把手帮你搞定,5分钟内看到丝滑的父/子节点加载树!