You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何将WYSIWYG生成的标题转为多维结构用于目录组件?

在React中构建WYSIWYG编辑器内容的层级目录

嘿,你现在把h1、h2、h3分别存成独立数组的做法,虽然能把所有标题都提取出来,但最大的问题是丢失了它们之间的层级关联——毕竟h2是属于最近的那个h1的,h3是跟着最近的h2走的,分开存三个数组就没法对应这种父子关系啦。

更合适的方式是用嵌套对象结构来存储,每个节点包含title(标题文本)和children(子标题数组)两个属性,这样后续渲染成有序列表时,递归遍历起来会非常方便。

具体实现步骤

1. 按顺序提取所有标题(保留层级信息)

首先不要分开匹配h1、h2、h3,而是用一个正则一次性提取所有标题,同时记录它们的层级(h1对应level=1,以此类推):

const str = "<h1>h1-1</h1><h2>h2-1</h2><h3>h3-1</h3><p>something</p><h1>h1-2</h1><h2>h2-2</h2><h3>h3-2</h3>";
// 匹配h1-h3,捕获层级数字和标题文本
const headingPattern = /<h([1-3])>(.*?)<\/h\1>/g;
let matches;
const allHeadings = [];

// 遍历所有匹配结果,收集成带层级的数组
while ((matches = headingPattern.exec(str)) !== null) {
  allHeadings.push({
    level: parseInt(matches[1], 10),
    title: matches[2]
  });
}

2. 构建嵌套层级结构

接下来用栈来维护当前的层级路径,遍历所有标题,把它们放到对应的父节点下:

const buildHierarchy = (headings) => {
  const hierarchy = []; // 最终的层级结构数组
  const stack = []; // 用来跟踪当前的层级路径

  headings.forEach(heading => {
    const currentNode = { title: heading.title, children: [] };

    // 弹出栈中所有层级 >= 当前标题层级的节点,找到当前节点的父节点
    while (stack.length > 0 && stack[stack.length - 1].level >= heading.level) {
      stack.pop();
    }

    if (stack.length === 0) {
      // 栈为空,说明是顶级h1,直接加入根数组
      hierarchy.push(currentNode);
    } else {
      // 把当前节点加到父节点的children数组中
      stack[stack.length - 1].children.push(currentNode);
    }

    // 将当前节点(带层级)压入栈,作为后续子标题的父节点候选
    stack.push({ ...currentNode, level: heading.level });
  });

  return hierarchy;
};

// 生成最终的层级目录结构
const tocHierarchy = buildHierarchy(allHeadings);

3. React组件递归渲染层级目录

最后写一个递归的React组件,把这个嵌套结构渲染成有序列表:

// 单个目录项组件
const TocItem = ({ item }) => {
  return (
    <li>
      {item.title}
      {/* 如果有子标题,递归渲染子列表 */}
      {item.children.length > 0 && (
        <ol>
          {item.children.map((child, idx) => (
            <TocItem key={idx} item={child} />
          ))}
        </ol>
      )}
    </li>
  );
};

// 目录总组件
const TableOfContents = ({ hierarchy }) => {
  return (
    <ol>
      {hierarchy.map((item, idx) => (
        <TocItem key={idx} item={item} />
      ))}
    </ol>
  );
};

// 使用示例
// <TableOfContents hierarchy={tocHierarchy} />

这样生成的结构就完全符合你想要的层级关系了,而且后续如果要扩展h4,只需要修改正则和层级判断逻辑就行,扩展性很强。

内容的提问来源于stack exchange,提问作者totalnoob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:21:31