jQuery EasyUI 树形菜单 – 创建复杂树形网格(一文讲透)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 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 性能优化建议

  • 数据分页:对海量数据使用 pageSizepageNumber 控制加载量。
  • 懒加载:仅在节点展开时加载子节点数据。
  • 缓存机制:通过 cache 参数避免重复请求相同节点。

3.3 常见问题解答

Q:树形菜单无法展开子节点?
A:检查数据格式是否包含 children 字段,或是否正确设置 parentField

Q:网格加载数据后列不对齐?
A:确保 columns 配置的 field 与返回的 JSON 字段名称一致。


四、结论

通过本文的讲解,开发者可以掌握 jQuery EasyUI 树形菜单 – 创建复杂树形网格 的核心方法。从基础树形结构到动态数据联动,再到性能优化,这一过程既涉及组件配置,也需结合业务逻辑设计。

对于初学者,建议从静态数据开始练习,逐步过渡到异步加载和复杂交互;中级开发者则可探索自定义渲染、拖拽排序等高级功能。记住,实践是掌握 EasyUI 的关键——尝试将本文的代码示例与实际项目结合,逐步构建出符合需求的树形网格系统。

如需进一步深入,可参考官方文档或查阅 EasyUI 的扩展插件,例如 treegrid 组件,它能直接将树形结构与网格合并,实现更简洁的代码。

最新发布