下面直接给你最实用、最常见的创建异步树形菜单(Async Tree / 懒加载树)方法,jQuery EasyUI 的 tree 组件支持超级简单的异步加载(点击节点时才向服务器请求子节点),复制粘贴就能做出左侧导航菜单、部门无限级组织架构、商品多级分类等,领导最爱的“只加载需要的数据,速度飞快”效果全都有!
方法1:最简单最常用 – 基本异步树形菜单(推荐现在就用这个,3秒出效果)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EasyUI 异步树形菜单</title>
<link rel="stylesheet" type="text/css" href="https://www.jeasyui.com/easyui/themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="https://www.jeasyui.com/easyui/themes/icon.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="https://www.jeasyui.com/easyui/jquery.easyui.min.js"></script>
</head>
<body>
<div style="width:280px;margin:30px auto;">
<!-- 异步树,只需要一个空ul即可 -->
<ul id="asyncTree" class="easyui-tree" data-options="
url:'get_root_nodes.php', <!-- 第一次加载根节点 -->
method:'get',
animate:true,
lines:true,
loadFilter: function(data){
return data; // 可以在这里统一处理返回格式
}
"></ul>
</div>
<script>
// 关键:绑定 onBeforeExpand 事件,在展开前异步加载子节点
$('#asyncTree').tree({
onBeforeExpand: function(node){
// 动态修改当前节点的子节点加载地址(可以带参数)
$('#asyncTree').tree('options').url = 'get_child_nodes.php?parent_id=' + node.id;
},
onClick: function(node){
if(node.url){
// 示例:打开右侧tab
addTab(node.text, node.url);
} else {
$.messager.show({
title:'提示',
msg:'你点击了:' + node.text + '(ID: ' + node.id + ')',
timeout:2000
});
}
}
});
</script>
</body>
</html>
后台接口示例(PHP)
- get_root_nodes.php(加载根节点)
<?php
// 模拟根节点
$data = [
['id'=>1, 'text'=>'系统管理', 'state'=>'closed', 'iconCls'=>'icon-setting'],
['id'=>2, 'text'=>'商品中心', 'state'=>'closed', 'iconCls'=>'icon-product'],
['id'=>3, 'text'=>'订单管理', 'state'=>'closed', 'iconCls'=>'icon-order'],
['id'=>4, 'text'=>'报表统计', 'url'=>'report.php', 'iconCls'=>'icon-chart']
];
echo json_encode($data);
?>
- get_child_nodes.php(根据父ID加载子节点)
<?php
$parent_id = $_GET['parent_id'] ?? 0;
// 模拟子节点数据(实际从数据库查)
$children = [];
if($parent_id == 1){
$children = [
['id'=>11, 'text'=>'用户管理', 'url'=>'user_list.php'],
['id'=>12, 'text'=>'角色管理', 'url'=>'role_list.php'],
['id'=>13, 'text'=>'部门管理', 'state'=>'closed'] // 有子节点,继续异步加载
];
} elseif($parent_id == 13){
$children = [
['id'=>131, 'text'=>'技术部'],
['id'=>132, 'text'=>'市场部'],
['id'=>133, 'text'=>'财务部']
];
}
// ... 其他节点
echo json_encode($children);
?>
效果亮点:
- 页面打开只加载根节点,速度超快
- 点击有子节点的“+”号时才异步请求子节点
- 支持无限级异步加载(部门组织架构完美)
state:'closed'表示有子节点但未加载
方法2:结合左侧布局 + 右侧tabs(完整后台框架异步树菜单)
<div class="easyui-layout" data-options="fit:true">
<!-- 左侧异步树菜单 -->
<div data-options="region:'west',title:'系统菜单',iconCls:'icon-tree',split:true" style="width:250px;">
<ul id="menuTree" class="easyui-tree" data-options="
url:'get_menu_root.php',
animate:true,
lines:true
"></ul>
</div>
<!-- 右侧主内容 -->
<div data-options="region:'center'">
<div id="mainTabs" class="easyui-tabs" data-options="fit:true,border:false">
<div title="首页" style="padding:20px;">欢迎使用EasyUI后台管理系统</div>
</div>
</div>
</div>
<script>
$('#menuTree').tree({
onBeforeExpand: function(node){
$('#menuTree').tree('options').url = 'get_menu_children.php?parent_id=' + node.id;
},
onClick: function(node){
if(node.url && node.url != ''){
addTab(node.text, node.url);
}
}
});
function addTab(title, url){
if($('#mainTabs').tabs('exists', title)){
$('#mainTabs').tabs('select', title);
} else {
$('#mainTabs').tabs('add',{
title: title,
content: '<iframe src="'+url+'" style="width:100%;height:100%;border:0;" frameborder="0"></iframe>',
closable: true
});
}
}
</script>
方法3:使用 loadFilter 统一处理返回数据(推荐大项目用)
$('#asyncTree').tree({
url: 'get_nodes.php',
loadFilter: function(data){
// 统一转换后台返回格式为EasyUI需要的格式
var result = [];
$.each(data, function(i, item){
result.push({
id: item.id,
text: item.name,
state: item.hasChild ? 'closed' : 'open',
iconCls: item.icon,
url: item.url,
attributes: item.attributes
});
});
return result;
}
});
你现在直接复制方法1的完整代码 + 两个PHP接口示例,放到服务器运行,就能看到一个超级流畅的异步树形菜单了!
特别适合数据量大的菜单、部门树、商品分类树等场景,加载速度飞快。
想要我给你一个完整的后台框架示例(异步树菜单 + 右侧tabs + 带图标 + 节点右键菜单)?
或者你告诉我你的节点接口返回格式(比如{id,pid,name,hasChild}),我2分钟帮你改好loadFilter,复制就能跑!
快说说你的具体需求,我手把手帮你搞定,5分钟内看到丝滑异步树形菜单效果!