Bootstrap Table 树形表格插件详解:treegrid 扩展实战

Bootstrap Table 树形表格插件详解:treegrid 扩展实战

【免费下载链接】bootstrap-table wenzhixin/bootstrap-table: 是一个基于 Bootstrap 的表格插件,它没有使用数据库。适合用于数据展示,特别是对于需要使用 Bootstrap 和表格展示的场景。特点是表格插件、Bootstrap、无数据库。 【免费下载链接】bootstrap-table 项目地址: https://gitcode.com/gh_mirrors/bo/bootstrap-table

1. 痛点解析:传统表格的层级数据展示困境

你是否还在为以下问题困扰?

  • 层级数据(如部门结构、分类目录)在普通表格中展示混乱
  • 大量展开/折叠按钮占据表格空间,影响数据密度
  • 树形结构与表格排序、分页功能冲突
  • 自定义树形样式需要编写大量额外代码

本文将系统讲解 Bootstrap Table 的 treegrid 扩展,通过 5 个实战案例和 3 种高级技巧,帮助你在 30 分钟内掌握层级数据的优雅展示方案。

2. 核心概念与工作原理

2.1 基本定义

树形表格(TreeGrid)是一种能够展示具有层级关系数据的表格组件,它通过缩进和连接线直观呈现父子关系,同时保留普通表格的排序、筛选和分页功能。

2.2 实现原理

mermaid

treegrid 扩展通过以下机制实现树形展示:

  1. 解析数据中的父子关系字段(idField 和 parentIdField)
  2. 递归构建 DOM 结构,通过 CSS 实现层级缩进
  3. 集成 jquery-treegrid 实现连接线渲染
  4. 重写表格行初始化方法,保持与 Bootstrap Table 核心功能兼容

3. 快速开始:5 分钟实现基础树形表格

3.1 引入必要资源

<!-- 引入依赖 -->
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/jquery-treegrid/0.3.0/css/jquery.treegrid.min.css">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery-treegrid/0.3.0/js/jquery.treegrid.min.js"></script>

<!-- 引入Bootstrap Table核心文件 -->
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/bootstrap-table/1.22.1/bootstrap-table.min.css">
<script src="https://cdn.bootcdn.net/ajax/libs/bootstrap-table/1.22.1/bootstrap-table.min.js"></script>

<!-- 引入treegrid扩展 -->
<script src="https://cdn.bootcdn.net/ajax/libs/bootstrap-table/1.22.1/extensions/treegrid/bootstrap-table-treegrid.min.js"></script>

3.2 HTML结构

<table id="treeTable" class="table table-striped table-bordered"></table>

3.3 JavaScript初始化

$('#treeTable').bootstrapTable({
  url: 'data.json',
  treeEnable: true,
  treeShowField: 'name',
  idField: 'id',
  parentIdField: 'pid',
  rootParentId: 0,
  columns: [
    { field: 'name', title: '名称' },
    { field: 'code', title: '编码' },
    { field: 'level', title: '层级' },
    { field: 'status', title: '状态' }
  ]
});

3.4 示例数据格式

[
  { "id": 1, "pid": 0, "name": "总公司", "code": "COMPANY", "level": 1, "status": "正常" },
  { "id": 2, "pid": 1, "name": "技术部", "code": "TECH", "level": 2, "status": "正常" },
  { "id": 3, "pid": 1, "name": "市场部", "code": "MARKET", "level": 2, "status": "正常" },
  { "id": 4, "pid": 2, "name": "前端团队", "code": "FRONTEND", "level": 3, "status": "正常" },
  { "id": 5, "pid": 2, "name": "后端团队", "code": "BACKEND", "level": 3, "status": "正常" },
  { "id": 6, "pid": 4, "name": "UI组", "code": "UI", "level": 4, "status": "正常" },
  { "id": 7, "pid": 4, "name": "JS组", "code": "JS", "level": 4, "status": "维护中" }
]

3.5 效果展示

┌──────────┬──────────┬──────┬────────┐
│ 名称     │ 编码     │ 层级 │ 状态   │
├──────────┼──────────┼──────┼────────┤
│ 总公司   │ COMPANY  │ 1    │ 正常   │
│ ├技术部  │ TECH     │ 2    │ 正常   │
│ │ ├前端团队│ FRONTEND │ 3    │ 正常   │
│ │ │ ├UI组  │ UI       │ 4    │ 正常   │
│ │ │ └JS组  │ JS       │ 4    │ 维护中 │
│ │ └后端团队│ BACKEND  │ 3    │ 正常   │
│ └市场部  │ MARKET   │ 2    │ 正常   │
└──────────┴──────────┴──────┴────────┘

4. 核心配置项详解

配置项数据类型默认值描述重要性
treeEnableBooleanfalse是否启用树形表格功能★★★★★
treeShowFieldStringnull指定作为树形展示的字段名,设置后自动启用树形功能★★★★★
idFieldString'id'数据唯一标识字段名★★★★★
parentIdFieldString'pid'父节点标识字段名★★★★★
rootParentIdAnynull根节点的父ID值★★★★☆

4.1 treeEnable 与 treeShowField 的关系

mermaid

最佳实践:推荐使用 treeShowField 配置,它会自动启用树形功能并指定展开/折叠图标位置。

5. 实战案例

5.1 案例一:部门人员层级表

需求:展示公司部门和人员的层级关系,支持按姓名搜索和职位筛选。

$('#deptTable').bootstrapTable({
  data: departmentData,
  treeShowField: 'name',
  idField: 'id',
  parentIdField: 'parentId',
  rootParentId: null,
  search: true,
  columns: [
    { 
      field: 'name', 
      title: '名称',
      formatter: function(value, row) {
        // 自定义图标区分部门和人员
        const icon = row.type === 'dept' ? 'folder' : 'user';
        return `<i class="glyphicon glyphicon-${icon}"></i> ${value}`;
      }
    },
    { field: 'title', title: '职位' },
    { field: 'email', title: '邮箱' },
    { field: 'phone', title: '电话' },
    { 
      field: 'action', 
      title: '操作',
      formatter: function() {
        return '<button class="btn btn-xs btn-primary">编辑</button>';
      }
    }
  ]
});

5.2 案例二:文件目录浏览器

需求:模拟文件系统目录结构,支持双击展开/折叠,右键菜单操作。

$('#fileExplorer').bootstrapTable({
  data: fileData,
  treeShowField: 'name',
  idField: 'id',
  parentIdField: 'pid',
  rootParentId: 0,
  clickToSelect: true,
  onDblClickCell: function(field, value, row, $element) {
    // 双击切换展开/折叠状态
    if (field === 'name') {
      const $tr = $element.closest('tr');
      if ($tr.hasClass('treegrid-collapsed')) {
        $tr.treegrid('expand');
      } else if ($tr.hasClass('treegrid-expanded')) {
        $tr.treegrid('collapse');
      }
    }
  },
  columns: [
    { 
      field: 'name', 
      title: '文件名',
      formatter: function(value, row) {
        const icon = row.isDir ? 'folder-open' : 'file';
        return `<i class="glyphicon glyphicon-${icon}"></i> ${value}`;
      }
    },
    { field: 'size', title: '大小', formatter: v => v || '-' },
    { field: 'modifyTime', title: '修改时间' }
  ]
});

// 初始化右键菜单
$('#fileExplorer').on('contextmenu', 'tr', function(e) {
  e.preventDefault();
  // 显示自定义右键菜单
  $('#fileContextMenu').css({
    top: e.pageY,
    left: e.pageX
  }).show();
});

5.3 案例三:树形结构与分页混合使用

需求:大数据量层级结构,需要分页加载子节点数据。

$('#bigDataTree').bootstrapTable({
  url: '/api/tree-data',
  treeShowField: 'name',
  idField: 'id',
  parentIdField: 'pid',
  rootParentId: 0,
  sidePagination: 'server',
  pagination: true,
  pageSize: 10,
  onLoadSuccess: function(data) {
    // 初始化treegrid
    $('#bigDataTree').treegrid({
      initialState: 'collapsed',
      expanderExpandedClass: 'glyphicon glyphicon-chevron-down',
      expanderCollapsedClass: 'glyphicon glyphicon-chevron-right'
    });
  },
  columns: [
    { field: 'name', title: '名称' },
    { field: 'code', title: '编码' },
    { field: 'desc', title: '描述' }
  ]
});

后端API设计

GET /api/tree-data?page=1&rows=10&parentId=0  // 获取根节点
GET /api/tree-data?page=1&rows=10&parentId=1  // 获取ID=1的子节点

6. 高级技巧与定制化

6.1 自定义展开/折叠图标

/* 自定义展开/折叠图标样式 */
.treegrid-expander {
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="5 9 12 16 19 9"></polyline></svg>');
  width: 16px;
  height: 16px;
}

.treegrid-collapsed .treegrid-expander {
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 5 12 8 15 5"></polyline><polyline points="9 19 12 16 15 19"></polyline></svg>');
}

6.2 动态加载子节点

// 实现点击展开时才加载子节点数据
$('#dynamicTree').bootstrapTable({
  data: rootData,  // 仅加载根节点数据
  treeShowField: 'name',
  idField: 'id',
  parentIdField: 'pid',
  onExpandRow: function(index, row, $detail) {
    // 检查是否已加载过子节点
    if (!row.childrenLoaded) {
      $.get(`/api/children/${row.id}`, function(data) {
        // 添加子节点数据
        $('#dynamicTree').bootstrapTable('append', data);
        // 标记为已加载
        row.childrenLoaded = true;
      });
    }
  },
  columns: [/* 列定义 */]
});

6.3 树形表格与拖拽排序结合

// 集成拖拽功能
$('#draggableTree').bootstrapTable({
  treeShowField: 'name',
  idField: 'id',
  parentIdField: 'pid',
  // 其他配置...
})
// 初始化拖拽
$('#draggableTree').find('tbody').sortable({
  items: 'tr:not(.has-children)',
  cursor: 'move',
  update: function(event, ui) {
    const movedRow = ui.item;
    const newParent = movedRow.prev();
    const newParentId = newParent.data('uniqueid') || null;
    
    // 发送更新请求
    $.post('/api/update-position', {
      id: movedRow.data('uniqueid'),
      newParentId: newParentId,
      newOrder: movedRow.index()
    });
  }
});

7. 常见问题与解决方案

7.1 问题:树形表格与分页功能冲突

原因:默认分页会将数据分割成多页,破坏树形结构的完整性。

解决方案

  1. 对于少量数据:禁用分页 (pagination: false)
  2. 对于大量数据:实现服务端树形分页(见5.3案例)
  3. 使用虚拟滚动 (virtualScroll: true) 替代传统分页

7.2 问题:搜索功能无法匹配子节点

解决方案:重写搜索逻辑,实现递归搜索

$.fn.bootstrapTable.locales['zh-CN'].formatSearch = function() {
  return '搜索所有层级:';
};

// 重写搜索方法
$.fn.bootstrapTable.Constructor.prototype.onSearch = function(event) {
  event.preventDefault();
  const searchText = this.$searchInput.val().toLowerCase();
  
  if (this.options.treeEnable) {
    // 树形表格搜索逻辑
    this.data = this.options.data.filter(row => {
      // 递归检查节点及其所有后代
      const hasMatch = (node) => {
        // 检查当前节点
        if (JSON.stringify(node).toLowerCase().includes(searchText)) {
          return true;
        }
        // 检查子节点
        const children = this.options.data.filter(child => 
          child[this.options.parentIdField] === node[this.options.idField]
        );
        return children.some(hasMatch);
      };
      
      // 只返回根节点或匹配节点
      return hasMatch(row) && 
             (row[this.options.parentIdField] === this.options.rootParentId);
    });
    this.initBody();
  } else {
    // 调用默认搜索方法
    this._super(event);
  }
};

7.3 问题:连接线样式不显示或错位

解决方案

  1. 确保正确引入 jquery-treegrid 的 CSS 文件
  2. 检查表格是否设置了固定列(fixedColumns),两者可能冲突
  3. 自定义连接线样式适配你的表格布局:
/* 修复连接线显示问题 */
.treegrid-indent {
  width: 24px;
  display: inline-block;
}

/* 调整连接线位置 */
.treegrid-expander {
  margin-left: -16px;
  margin-right: 8px;
}

8. 性能优化策略

对于超过1000行的大型树形表格,建议采用以下优化措施:

  1. 数据分片加载:只加载当前展开节点的子节点(见6.2案例)
  2. 虚拟滚动:启用 virtualScroll: true,只渲染可视区域内的行
  3. 延迟渲染:使用 deferRender: true 延迟DOM创建
  4. CSS优化:避免使用复杂选择器和阴影效果
  5. 事件委托:将事件绑定到表格而非单个行
// 高性能配置示例
{
  treeEnable: true,
  treeShowField: 'name',
  virtualScroll: true,
  virtualScrollItemHeight: 38,
  deferRender: true,
  pageSize: 200,  // 虚拟滚动每页大小
  cache: true,    // 启用缓存
  // 其他配置...
}

9. 总结与展望

Bootstrap Table 的 treegrid 扩展为层级数据展示提供了简洁而强大的解决方案,其核心优势包括:

  • 与 Bootstrap Table 无缝集成,保留所有原有功能
  • 简洁的配置 API,降低使用门槛
  • 灵活的扩展性,支持自定义图标、样式和行为
  • 轻量级实现,性能表现优异

未来发展方向

  1. 原生支持虚拟滚动树形结构
  2. 内置拖拽排序功能
  3. 支持更复杂的树形数据结构(如多父节点)
  4. 增强无障碍访问支持

掌握 treegrid 扩展不仅能提升数据展示的美观度,更能显著改善用户对层级数据的理解和操作效率。建议结合实际项目需求,灵活运用本文介绍的配置项和高级技巧,打造专业级的树形表格体验。

10. 学习资源与社区

  • 官方文档:Bootstrap Table 官方扩展文档
  • GitHub仓库:https://gitcode.com/gh_mirrors/bo/bootstrap-table
  • 示例集合:examples.bootstrap-table.com/#extensions/treegrid.html
  • 社区支持:StackOverflow 上的 bootstrap-table 标签

实践作业:尝试实现一个"多级评论系统",要求支持无限层级嵌套、评论点赞和回复功能,巩固本文所学知识。

【免费下载链接】bootstrap-table wenzhixin/bootstrap-table: 是一个基于 Bootstrap 的表格插件,它没有使用数据库。适合用于数据展示,特别是对于需要使用 Bootstrap 和表格展示的场景。特点是表格插件、Bootstrap、无数据库。 【免费下载链接】bootstrap-table 项目地址: https://gitcode.com/gh_mirrors/bo/bootstrap-table

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值