首页
/ layui树形表格treeTable:复杂数据结构的可视化展示

layui树形表格treeTable:复杂数据结构的可视化展示

2026-02-04 04:34:10作者:姚月梅Lane

还在为展示层级数据而烦恼吗?面对复杂的树形结构数据,传统的表格无法清晰展示父子关系,而layui的treeTable组件正是解决这一痛点的利器。本文将带你全面掌握layui treeTable的使用技巧,从基础配置到高级功能,助你轻松应对各种复杂数据结构可视化需求。

什么是treeTable?

treeTable是layui基于table组件扩展的树形表格组件,它完美结合了表格的数据展示能力和树形结构的层级关系,支持常见的树组件功能如展开/折叠、节点操作、异步加载等。

核心优势

  • 层级展示:清晰展示父子节点关系,支持无限级嵌套
  • 功能丰富:继承table所有功能,支持排序、分页、复选框等
  • 操作便捷:内置节点增删改查、展开折叠等操作
  • 异步支持:支持按需加载子节点,提升性能
  • 高度定制:可自定义图标、样式、事件回调

快速入门

基础配置

首先引入layui资源:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>treeTable示例</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/layui@2.9.7/dist/css/layui.css">
</head>
<body>
  <table id="demo-treeTable"></table>
  
  <script src="https://cdn.jsdelivr.net/npm/layui@2.9.7/dist/layui.js"></script>
  <script>
  layui.use(['treeTable'], function(){
    var treeTable = layui.treeTable;
    
    // 渲染treeTable
    treeTable.render({
      elem: '#demo-treeTable',
      url: '/api/tree-data', // 数据接口
      tree: {
        // treeTable特定配置
      },
      cols: [[
        {type: 'checkbox'},
        {field: 'id', title: 'ID', width: 80},
        {field: 'name', title: '名称', width: 200},
        {field: 'type', title: '类型', width: 100},
        {field: 'createTime', title: '创建时间', width: 150}
      ]]
    });
  });
  </script>
</body>
</html>

数据结构要求

treeTable支持两种数据格式:

1. 树形结构数据(默认)

{
  "code": 0,
  "data": [
    {
      "id": 1,
      "name": "父节点1",
      "children": [
        {
          "id": 2,
          "name": "子节点1-1",
          "children": [
            {
              "id": 3,
              "name": "孙子节点1-1-1"
            }
          ]
        }
      ]
    }
  ]
}

2. 平铺结构数据

{
  "code": 0,
  "data": [
    {"id": 1, "name": "节点1", "parentId": null},
    {"id": 2, "name": "节点2", "parentId": 1},
    {"id": 3, "name": "节点3", "parentId": 2}
  ]
}

使用时需要设置 tree.data.isSimpleData: true

核心功能详解

1. 基础配置选项

treeTable的配置分为两部分:table基础配置和tree特定配置。

treeTable.render({
  // table基础配置
  elem: '#demo',
  url: '/api/data',
  page: true,
  cols: [[...]],
  
  // tree特定配置
  tree: {
    customName: {
      id: 'id',           // 节点ID字段名
      name: 'name',       // 节点名称字段名  
      children: 'children', // 子节点字段名
      parentId: 'parentId', // 父节点ID字段名
      isParent: 'isParent'  // 是否为父节点字段名
    },
    view: {
      indent: 14,         // 层级缩进量
      showIcon: true,     // 是否显示图标
      expandAllDefault: false // 是否默认展开所有节点
    },
    data: {
      isSimpleData: false, // 是否使用平铺数据
      rootPid: null       // 根节点的parentId值
    }
  }
});

2. 异步加载子节点

对于大数据量的场景,可以使用异步加载提升性能:

treeTable.render({
  elem: '#demo',
  tree: {
    async: {
      enable: true, // 开启异步加载
      url: '/api/children', // 子节点接口
      autoParam: ['parentId=id'] // 自动传参规则
    }
  }
});

3. 事件处理

treeTable支持丰富的事件回调:

// 节点展开前回调
tree: {
  callback: {
    beforeExpand: function(tableId, trData, expandFlag) {
      console.log('即将展开节点:', trData.name);
      // 返回false可取消展开
    },
    onExpand: function(tableId, trData, expandFlag) {
      console.log('节点已' + (expandFlag ? '展开' : '折叠'));
    }
  }
}

// 监听工具事件
treeTable.on('tool(demo)', function(obj){
  var event = obj.event;
  var data = obj.data;
  
  if(event === 'edit') {
    // 编辑操作
  } else if(event === 'delete') {
    // 删除操作
  }
});

实战案例:组织架构管理

让我们通过一个完整的组织架构管理案例来展示treeTable的强大功能。

数据结构设计

{
  "code": 0,
  "data": [
    {
      "id": 1,
      "name": "总公司",
      "type": "company",
      "manager": "张三",
      "employeeCount": 1000,
      "children": [
        {
          "id": 2,
          "name": "技术部",
          "type": "department", 
          "manager": "李四",
          "employeeCount": 200,
          "children": [
            {
              "id": 3,
              "name": "前端组",
              "type": "team",
              "manager": "王五",
              "employeeCount": 20
            }
          ]
        }
      ]
    }
  ]
}

完整实现代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>组织架构管理</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/layui@2.9.7/dist/css/layui.css">
  <style>
    .org-tree { margin: 20px; }
    .org-icon { margin-right: 5px; }
  </style>
</head>
<body>
<div class="org-tree">
  <table id="org-table" lay-filter="org-table"></table>
</div>

<script type="text/html" id="toolbar">
  <div class="layui-btn-container">
    <button class="layui-btn layui-btn-sm" lay-event="expandAll">展开全部</button>
    <button class="layui-btn layui-btn-sm" lay-event="collapseAll">折叠全部</button>
    <button class="layui-btn layui-btn-sm layui-btn-normal" lay-event="addRoot">添加根部门</button>
  </div>
</script>

<script type="text/html" id="row-tool">
  <div class="layui-btn-container">
    <a class="layui-btn layui-btn-xs layui-btn-primary" lay-event="view">查看</a>
    <a class="layui-btn layui-btn-xs layui-btn-warm" lay-event="addChild">添加子部门</a>
    <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
    <a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="delete">删除</a>
  </div>
</script>

<script src="https://cdn.jsdelivr.net/npm/layui@2.9.7/dist/layui.js"></script>
<script>
layui.use(['treeTable', 'layer', 'dropdown'], function(){
  var treeTable = layui.treeTable;
  var layer = layui.layer;
  var dropdown = layui.dropdown;

  // 渲染组织架构表格
  var inst = treeTable.render({
    elem: '#org-table',
    url: '/api/organization',
    toolbar: '#toolbar',
    tree: {
      view: {
        indent: 20,
        icon: function(data) {
          // 根据类型显示不同图标
          var icons = {
            company: 'layui-icon layui-icon-group',
            department: 'layui-icon layui-icon-template-1',
            team: 'layui-icon layui-icon-user'
          };
          return '<i class="' + (icons[data.type] || 'layui-icon layui-icon-file') + ' org-icon"></i>';
        }
      }
    },
    cols: [[
      {field: 'name', title: '部门名称', width: 250, templet: function(d){
        return d.name + ' <span class="layui-badge">' + d.employeeCount + '</span>';
      }},
      {field: 'type', title: '类型', width: 100, templet: function(d){
        var types = {company: '公司', department: '部门', team: '小组'};
        return types[d.type] || d.type;
      }},
      {field: 'manager', title: '负责人', width: 120},
      {field: 'employeeCount', title: '人数', width: 80, sort: true},
      {fixed: 'right', title: '操作', width: 250, toolbar: '#row-tool'}
    ]],
    page: false
  });

  // 工具栏事件
  treeTable.on('toolbar(org-table)', function(obj){
    var tableId = inst.config.id;
    
    switch(obj.event) {
      case 'expandAll':
        treeTable.expandAll(tableId, true);
        break;
      case 'collapseAll':
        treeTable.expandAll(tableId, false);
        break;
      case 'addRoot':
        layer.prompt({
          title: '请输入根部门名称',
        }, function(value, index){
          treeTable.addNodes(tableId, {
            data: {
              id: Date.now(),
              name: value,
              type: 'department',
              manager: '待分配',
              employeeCount: 0
            }
          });
          layer.close(index);
        });
        break;
    }
  });

  // 行工具事件
  treeTable.on('tool(org-table)', function(obj){
    var data = obj.data;
    var tableId = inst.config.id;
    
    switch(obj.event) {
      case 'view':
        layer.alert('部门详情:' + JSON.stringify(data, null, 2));
        break;
      case 'addChild':
        layer.prompt({
          title: '请输入子部门名称',
        }, function(value, index){
          treeTable.addNodes(tableId, {
            parentIndex: data.LAY_DATA_INDEX,
            data: {
              id: Date.now(),
              name: value,
              type: data.type === 'team' ? 'team' : 'department',
              manager: '待分配',
              employeeCount: 0
            }
          });
          layer.close(index);
        });
        break;
      case 'edit':
        layer.prompt({
          title: '修改部门名称',
          value: data.name
        }, function(value, index){
          treeTable.updateNode(tableId, data.LAY_DATA_INDEX, {
            name: value
          });
          layer.close(index);
        });
        break;
      case 'delete':
        layer.confirm('确定删除该部门?', function(index){
          treeTable.removeNode(tableId, data.LAY_DATA_INDEX);
          layer.close(index);
        });
        break;
    }
  });
});
</script>
</body>
</html>

高级技巧与最佳实践

1. 性能优化策略

// 大数据量时启用虚拟滚动
treeTable.render({
  // ...
  scroll: {
    enable: true, // 开启虚拟滚动
    maxHeight: 500 // 最大高度
  }
});

// 按需加载子节点
tree: {
  async: {
    enable: true,
    url: '/api/children',
    autoParam: ['parentId=id', 'level=level']
  }
}

2. 自定义样式和图标

tree: {
  view: {
    // 自定义折叠图标
    flexIconClose: '<i class="layui-icon layui-icon-triangle-r"></i>',
    flexIconOpen: '<i class="layui-icon layui-icon-triangle-d"></i>',
    
    // 根据数据动态设置图标
    icon: function(data) {
      if(data.type === 'folder') {
        return data.expanded ? 
          '<i class="layui-icon layui-icon-folder-open"></i>' :
          '<i class="layui-icon layui-icon-folder"></i>';
      }
      return '<i class="layui-icon layui-icon-file"></i>';
    }
  }
}

3. 数据操作API汇总

API方法 描述 示例
treeTable.getData(id) 获取表格数据 var data = treeTable.getData('demo')
treeTable.addNodes(id, opts) 添加节点 treeTable.addNodes('demo', {parentIndex: 0, data: {...}})
treeTable.updateNode(id, index, data) 更新节点 treeTable.updateNode('demo', 0, {name: '新名称'})
treeTable.removeNode(id, index) 删除节点 treeTable.removeNode('demo', 0)
treeTable.expandAll(id, flag) 展开/折叠所有 treeTable.expandAll('demo', true)
treeTable.reloadData(id, options) 重载数据 treeTable.reloadData('demo', {url: '/new-data'})

常见问题与解决方案

Q1: 数据加载异常怎么办?

A: 检查数据格式是否符合要求,确保包含必要的字段(id、children/parentId)

Q2: 异步加载不生效?

A: 确认async.enable为true,并正确配置url和autoParam参数

Q3: 节点操作后界面不更新?

A: 使用treeTable提供的API方法(addNodes/updateNode等)而非直接操作DOM

Q4: 大数据量性能问题?

A: 启用虚拟滚动、使用异步加载、合理分页

总结

layui treeTable是一个功能强大、易于使用的树形表格组件,它完美解决了复杂层级数据的可视化展示问题。通过本文的学习,你应该已经掌握了:

  1. treeTable的基础配置和使用方法
  2. 两种数据格式的适配技巧
  3. 丰富的API操作和事件处理
  4. 性能优化和最佳实践
  5. 实际项目中的完整应用案例

无论是组织架构、文件系统、分类管理还是任何需要展示层级关系的场景,treeTable都能提供优雅的解决方案。现在就开始使用treeTable,让你的数据展示更加清晰和专业吧!

温馨提示:在实际项目中,记得根据具体需求调整配置,并做好错误处理和用户体验优化。如果遇到问题,可以查阅layui官方文档或社区讨论。

登录后查看全文
热门项目推荐
相关项目推荐