0

0

React Tabulator 嵌套数据行号自定义:实现层级小数位编号

霞舞

霞舞

发布时间:2025-12-05 11:58:02

|

471人浏览过

|

来源于php中文网

原创

react tabulator 嵌套数据行号自定义:实现层级小数位编号

本教程旨在解决 React Tabulator 在处理嵌套数据(树形结构)时,默认行号格式化器无法实现子行小数位层级编号的问题。我们将通过在数据加载到 Tabulator 之前进行预处理,递归地为每个父行和子行生成自定义的带小数位层级编号,并将其作为独立字段渲染,从而实现如“1.1”、“1.2”、“2.1”等效果。

在构建具有嵌套数据(例如树形表格)的用户界面时,使用 React Tabulator 是一个常见的选择。然而,当需要为这些嵌套行生成具有层级结构(如“1”、“1.1”、“1.2”、“2”、“2.1”)的自定义行号时,Tabulator 内置的 rownum 格式化器可能无法满足复杂的需求,尤其是在处理子行的编号时,它通常会显示为 0 或简单的独立计数。为了实现这种小数位层级编号,我们需要一种更灵活的方法,即在数据绑定到 Tabulator 之前,对原始数据进行预处理。

解决方案概述

核心思想是在将数据传递给 Tabulator 之前,通过一个递归函数遍历整个数据集。在遍历过程中,为每个数据项(包括父项和子项)计算并添加一个自定义的 rowNum 字段。这个 rowNum 字段将包含我们期望的层级小数位编号。之后,Tabulator 只需要渲染这个预先计算好的 rowNum 字段即可。

实现步骤

1. 准备原始数据结构

首先,我们需要一个包含嵌套结构的原始数据。Tabulator 通过 _children 字段来识别子行。

const tableData = [
  { name: 'Oli Bob', location: 'United Kingdom', gender: 'male', dob: '14/04/1984', _children: [
      { name: 'Mary May', location: 'Germany', gender: 'female', dob: '14/05/1982' },
      { name: 'Christine Lobowski', location: 'France', gender: 'female', dob: '22/05/1982' },
      { name: 'Brendon Philips', location: 'USA', gender: 'male', dob: '01/08/1980', _children: [
          { name: 'Margret Marmajuke', location: 'Canada', gender: 'female', dob: '31/01/1999' },
          { name: 'Frank Harbours', location: 'Russia', gender: 'male', dob: '12/05/1966' }
        ]
      }
    ]
  },
  { name: 'Jamie Newhart', location: 'India', gender: 'male', dob: '14/05/1985' },
  { name: 'Gemma Jane', location: 'China', gender: 'female', dob: '22/05/1982', _children: [
    { name: 'Emily Sykes', location: 'South Korea', gender: 'female', dob: '11/11/1970' }] },
    { name: 'James Newman', location: 'Japan', gender: 'male', dob: '22/03/1998' }
];

2. 递归生成自定义行号

创建一个递归函数,该函数将遍历数据数组,为每个元素计算其层级编号并存储在 rowNum 字段中。

/**
 * 递归地为表格数据添加层级行号
 * @param {Array<Object>} data - 当前层级的数据数组
 * @param {string} parentRowNum - 父级行的行号(例如 "1", "1.1"),顶级调用时为空
 */
const numberRows = (data, parentRowNum = '') => {
  data.forEach((row, index) => {
    // 构建当前行的行号
    // 如果有父级行号,则以父级行号为前缀,加上 '.' 和当前索引+1
    // 否则,直接使用当前索引+1
    row.rowNum = (parentRowNum ? parentRowNum + '.' : '') + (index + 1);

    // 如果当前行有子行,则递归调用自身处理子行
    if (row._children) {
      numberRows(row._children, row.rowNum);
    }
  });
};

// 调用函数处理原始数据
numberRows(tableData);

这个 numberRows 函数接受两个参数:当前层级的数据数组 data 和可选的 parentRowNum。

Glimmer Ai
Glimmer Ai

基于GPT-3和DALL·E2的PPT制作工具

下载
  • parentRowNum 用于构建子行的前缀,确保层级关系。
  • forEach 循环遍历当前层级的所有行。
  • row.rowNum 的计算逻辑是关键:如果存在 parentRowNum,则当前行号是 parentRowNum 加上 . 和当前行的索引加一;否则,它只是当前行的索引加一。
  • 如果当前行有 _children,则递归调用 numberRows 函数,并将当前行的 rowNum 作为新的 parentRowNum 传递给子层级。

3. 配置 React Tabulator

在 React Tabulator 组件中,将预处理后的 tableData 传递给 data 属性,并为 rowNum 字段定义一个普通列。

import React, { useRef, useEffect } from 'react';
import { ReactTabulator } from 'react-tabulator';
import 'react-tabulator/lib/styles.css'; // 导入样式
import 'tabulator-tables/dist/css/tabulator.min.css'; // 导入 Tabulator 基础样式

// ... (tableData 和 numberRows 函数定义如上)

// 假设 numberRows(tableData) 已经执行,tableData 已经被添加了 rowNum 字段

const columns = [
  { title: '', field: 'rowNum', width: 100, headerSort: false }, // 渲染自定义的 rowNum 字段
  { title: 'Name', field: 'name', width: 150 },
  { title: 'Location', field: 'location', width: 140 },
  { title: 'Gender', field: 'gender', width: 100 },
  { title: 'Date Of Birth', field: 'dob', width: 140 }
];

const TabulatorComponent = () => {
  const ref = useRef(null);

  const options = {
    height: '300px',
    data: tableData, // 使用已经预处理过的 tableData
    dataTree: true, // 启用数据树功能
    dataTreeStartExpanded: true, // 默认展开所有节点
    columns: columns,
  };

  return (
    <ReactTabulator
      ref={ref}
      options={options}
      data={tableData} // 再次传入 data,确保组件接收到更新后的数据
      columns={columns}
    />
  );
};

export default TabulatorComponent;

注意: 尽管示例代码中使用了 vanilla JS 的 Tabulator 实例化方式 (new Tabulator(...)),但在 React 环境中,您应该使用 react-tabulator 组件,并通过其 options 属性来传递配置。核心的数据结构和列定义逻辑是相同的。

完整示例代码 (Vanilla JS Tabulator)

为了方便测试和理解,这里提供一个完整的 HTML 和 JavaScript 示例,可以直接在浏览器中运行:

<!DOCTYPE html>
<html>
<head>
  <title>React Tabulator 自定义层级行号</title>
  <link href="https://unpkg.com/tabulator-tables@5.6.0/dist/css/tabulator.min.css" rel="stylesheet">
  <script type="text/javascript" src="https://unpkg.com/tabulator-tables@5.6.0/dist/js/tabulator.min.js"></script>
  <style>
    body { font-family: sans-serif; margin: 20px; }
    #table { margin-top: 20px; }
  </style>
</head>
<body>
  <h1>Tabulator 嵌套数据自定义行号示例</h1>
  <div id="table"></div>

  <script type="text/javascript">
    const tableData = [
      { name: 'Oli Bob', location: 'United Kingdom', gender: 'male', dob: '14/04/1984', _children: [
          { name: 'Mary May', location: 'Germany', gender: 'female', dob: '14/05/1982' },
          { name: 'Christine Lobowski', location: 'France', gender: 'female', dob: '22/05/1982' },
          { name: 'Brendon Philips', location: 'USA', gender: 'male', dob: '01/08/1980', _children: [
              { name: 'Margret Marmajuke', location: 'Canada', gender: 'female', dob: '31/01/1999' },
              { name: 'Frank Harbours', location: 'Russia', gender: 'male', dob: '12/05/1966' }
            ]
          }
        ]
      },
      { name: 'Jamie Newhart', location: 'India', gender: 'male', dob: '14/05/1985' },
      { name: 'Gemma Jane', location: 'China', gender: 'female', dob: '22/05/1982', _children: [
        { name: 'Emily Sykes', location: 'South Korea', gender: 'female', dob: '11/11/1970' }] },
        { name: 'James Newman', location: 'Japan', gender: 'male', dob: '22/03/1998' }
    ];

    // 添加行号的递归函数
    const numberRows = (data, parentRowNum = '') => {
      data.forEach((row, index) => {
        row.rowNum = (parentRowNum ? parentRowNum + '.' : '') + (index + 1);

        if (row._children) {
          numberRows(row._children, row.rowNum);
        }
      });
    };

    // 执行行号预处理
    numberRows(tableData);

    // Tabulator 表格实例化
    const table = new Tabulator('#table', {
      height: '300px',
      data: tableData, // 使用已经处理过的带行号的数据
      dataTree: true, // 启用数据树功能
      dataTreeStartExpanded: true, // 默认展开所有节点
      columns: [
        { title: '', field: 'rowNum', width: 100, headerSort: false }, // 渲染自定义的 rowNum 字段
        { title: 'Name', field: 'name', width: 150 },
        { title: 'Location', field: 'location', width: 140 },
        { title: 'Gender', field: 'gender', width: 100 },
        { title: 'Date Of Birth', field: 'dob', width: 140 }
      ]
    });
  </script>
</body>
</html>

注意事项与总结

  1. 数据预处理时机: 这种方法的核心在于在数据加载到 Tabulator 之前完成行号的生成。这意味着如果您在 Tabulator 中动态添加、删除或重新排序行,您需要重新运行 numberRows 函数来更新所有行号,然后刷新 Tabulator 的数据。
  2. 性能考量: 对于非常庞大且深度嵌套的数据集,递归处理可能会有轻微的性能开销。但在大多数常见场景下,这种开销是可接受的。
  3. 灵活性: 这种方法非常灵活。您可以根据需要修改 numberRows 函数,以生成不同格式的行号,例如罗马数字、字母序列或其他自定义编号方案。
  4. 解耦: 将行号生成逻辑从 Tabulator 的渲染机制中解耦出来,使得代码更易于维护和测试。Tabulator 只需要渲染一个普通的字段,而无需关心其复杂的生成逻辑。
  5. 替代方案: 理论上,Tabulator 的 formatter 属性可以用来定义复杂的渲染逻辑。但对于层级行号这种需要访问父级上下文才能确定自身编号的情况,直接在 formatter 中实现会非常复杂,甚至不可行,因为它通常只接收当前行的数据。因此,数据预处理是更推荐和简洁的方案。

通过上述方法,您可以轻松地在 React Tabulator 的嵌套数据中实现自定义的、具有小数位层级结构的行号显示,从而提升表格的可读性和用户体验。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

267

2025.12.04

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

549

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

30

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

44

2026.01.06

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

531

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

576

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

6230

2023.08.17

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

CSS教程
CSS教程

共754课时 | 42.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号