jQuery EasyUI 树形菜单 – 创建复杂树形网格(一文讲透)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
在现代 Web 开发中,树形菜单和网格(Grid)是两种核心的交互组件。它们分别以层级结构和表格形式展示数据,但在实际场景中,开发者经常需要将两者结合,形成更复杂的数据展示与操作界面。例如,电商后台需要通过树形菜单筛选商品分类,再通过网格展示对应的商品列表;项目管理系统需用树形结构展示部门层级,同时用网格呈现成员信息。
jQuery EasyUI 是一个功能强大的前端框架,其树形菜单(Tree)组件和网格(DataGrid)组件的组合,能够高效实现这种复杂需求。本文将从基础概念入手,逐步讲解如何通过 EasyUI 创建树形菜单,并深入探讨如何将树形结构与网格联动,最终构建出动态、交互性强的复杂树形网格。
一、环境准备与基础概念
1.1 开发环境搭建
要使用 jQuery EasyUI,需在 HTML 文件中引入以下资源:
<!-- 引入 jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- 引入 EasyUI 核心库 -->
<link rel="stylesheet" href="https://www.jeasyui.com/easyui/themes/default/easyui.css">
<link rel="stylesheet" href="https://www.jeasyui.com/easyui/themes/icon.css">
<script src="https://www.jeasyui.com/easyui/jquery.easyui.min.js"></script>
1.2 核心概念解析
1.2.1 树形菜单(Tree)
EasyUI 的树形菜单是一个基于 ul/li
结构的层级组件,通过配置 data-options
或 JavaScript 初始化,可以实现动态加载、展开/折叠节点、节点拖拽等功能。
1.2.2 数据格式
树形菜单的数据通常以 JSON 格式表示,每个节点包含以下属性:
id
: 节点唯一标识text
: 显示的文本state
: 初始状态(如open
表示展开)children
: 子节点数组(可选)
示例数据片段:
[
{
"id": 1,
"text": "电子产品",
"state": "closed",
"children": [
{ "id": 2, "text": "手机" },
{ "id": 3, "text": "笔记本电脑" }
]
}
]
1.2.3 事件与方法
EasyUI 树形菜单支持多种事件,例如:
onLoadSuccess
: 数据加载成功时触发onClick
: 节点被点击时触发onExpand
: 节点展开时触发
通过这些事件,可以实现与网格的联动逻辑。
二、案例实战:从简单树到复杂树形网格
2.1 创建基础树形菜单
2.1.1 HTML 结构
<div class="easyui-panel" title="基础树形菜单示例">
<ul id="treeDemo"></ul>
</div>
2.1.2 JavaScript 初始化
$(function() {
// 初始化树形菜单
$('#treeDemo').tree({
url: '/api/tree-data', // 假设后端接口返回 JSON 数据
method: 'GET',
onLoadSuccess: function() {
console.log('树形菜单加载完成');
}
});
});
2.1.3 效果说明
此代码通过异步请求加载数据,树形菜单会根据返回的 JSON 生成层级结构。若数据中包含 children
字段,则节点会自动展开为子节点。
2.2 添加动态交互:树形菜单与网格联动
2.2.1 需求分析
假设需要点击树形菜单的某个节点时,下方的网格展示该节点对应的数据。例如:
- 点击“手机”节点 → 网格显示所有手机型号
- 点击“笔记本电脑”节点 → 网格显示所有笔记本型号
2.2.2 HTML 结构扩展
<div class="easyui-panel" title="联动示例">
<div style="padding:5px;">
<ul id="tree联动"></ul>
</div>
<div id="grid联动"></div>
</div>
2.2.3 JavaScript 实现
$(function() {
// 初始化树形菜单
$('#tree联动').tree({
url: '/api/tree-data',
onLoadSuccess: function() {
// 默认展开根节点
$('#tree联动').tree('expandAll');
}
});
// 初始化网格
$('#grid联动').datagrid({
url: '/api/grid-data', // 默认加载根节点数据
columns: [[
{ field: 'id', title: 'ID', width: 100 },
{ field: 'name', title: '名称', width: 150 },
{ field: 'price', title: '价格', width: 100 }
]]
});
// 监听树形菜单的点击事件
$('#tree联动').tree({
onClick: function(node) {
// 根据节点 ID 加载对应数据
$('#grid联动').datagrid('load', {
nodeId: node.id
});
}
});
});
2.2.4 关键点解析
- 事件绑定:通过
onClick
事件触发网格的load
方法,传入当前节点的id
。 - 数据隔离:网格的
url
需支持按nodeId
过滤数据,例如:// 假设后端接口 /api/grid-data 处理参数 nodeId
2.3 构建复杂树形网格:异步加载与自定义渲染
2.3.1 异步加载子节点
在大型系统中,树形菜单的层级可能很深,一次性加载所有数据会降低性能。可通过 onBeforeLoad
事件实现按需加载:
$('#tree异步').tree({
url: '/api/root-nodes', // 只加载根节点
onBeforeLoad: function(node, param) {
// 根据父节点 ID 加载子节点
param.parentId = node.id;
return true; // 继续加载
}
});
2.3.2 自定义节点渲染
某些场景需要为节点添加图标或状态标识,可通过 onBeforeRender
事件自定义:
$('#tree自定义').tree({
onBeforeRender: function(node) {
// 为叶子节点添加图标
if (!node.children) {
node.iconCls = 'easyui-icon-ok';
}
return node;
}
});
2.3.3 网格的复杂配置
当网格需要支持分页、排序和自定义列时,可通过以下配置:
$('#grid复杂').datagrid({
url: '/api/data',
pagination: true,
rownumbers: true,
columns: [[
{ field: 'id', title: 'ID', sortable: true },
{ field: 'name', title: '名称', width: 200 },
{
field: 'status',
title: '状态',
formatter: function(value) {
return value === 'active' ? '启用' : '禁用';
}
}
]]
});
三、高级技巧与常见问题
3.1 树形菜单与网格的双向绑定
在需要双向更新的场景(如编辑节点后同步网格数据),可通过以下方式实现:
// 树形菜单的右键菜单示例
$('#tree编辑').tree({
onContextMenu: function(e, node) {
e.preventDefault();
$('#tree编辑').tree('select', node.target);
$('#menu').menu('show', {
left: e.pageX,
top: e.pageY
});
}
});
// 菜单点击触发更新
$('#menu-edit').click(function() {
const node = $('#tree编辑').tree('getSelected');
// 更新节点数据并刷新网格
updateNode(node.id).then(() => {
$('#grid关联').datagrid('reload');
});
});
3.2 性能优化建议
- 数据分页:对海量数据使用
pageSize
和pageNumber
控制加载量。 - 懒加载:仅在节点展开时加载子节点数据。
- 缓存机制:通过
cache
参数避免重复请求相同节点。
3.3 常见问题解答
Q:树形菜单无法展开子节点?
A:检查数据格式是否包含 children
字段,或是否正确设置 parentField
。
Q:网格加载数据后列不对齐?
A:确保 columns
配置的 field
与返回的 JSON 字段名称一致。
四、结论
通过本文的讲解,开发者可以掌握 jQuery EasyUI 树形菜单 – 创建复杂树形网格 的核心方法。从基础树形结构到动态数据联动,再到性能优化,这一过程既涉及组件配置,也需结合业务逻辑设计。
对于初学者,建议从静态数据开始练习,逐步过渡到异步加载和复杂交互;中级开发者则可探索自定义渲染、拖拽排序等高级功能。记住,实践是掌握 EasyUI 的关键——尝试将本文的代码示例与实际项目结合,逐步构建出符合需求的树形网格系统。
如需进一步深入,可参考官方文档或查阅 EasyUI 的扩展插件,例如 treegrid
组件,它能直接将树形结构与网格合并,实现更简洁的代码。