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

如何在Next.js+Markdown博客中实现类似LeetCode的标签页功能?

实现Next.js+Markdown博客的LeetCode风格标签页方法

LeetCode的标签页核心是顶部切换栏+对应内容区的结构,点击标签切换激活状态,同步展示对应内容。下面分步骤实现:

1. 自定义Markdown标签语法

原生Markdown不支持标签页,得自己定义一套简单语法,方便写博客时使用,示例:

:::tabs
:::tab 题目描述
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
:::tab 解题思路
用哈希表存遍历过的元素和下标,遍历数组时检查当前元素与target的差值是否在哈希表中,存在则直接返回结果。
:::tab 代码实现
```javascript
function twoSum(nums, target) {
    const map = new Map();
    for (let i = 0; i < nums.length; i++) {
        const complement = target - nums[i];
        if (map.has(complement)) {
            return [map.get(complement), i];
        }
        map.set(nums[i], i);
    }
}

:::

## 2. 解析Markdown中的标签页结构
用`remark`+`rehype`生态处理Markdown,写自定义插件识别上述语法,转换成React组件需要的结构:
- 先装依赖:`npm install remark-parse remark-rehype rehype-stringify unified`
- 写remark插件遍历Markdown的AST树,把`:::tabs`和`:::tab`块转换成Tabs组件可接收的结构:
```javascript
// remark-tabs-plugin.js
export function remarkTabs() {
  return (tree) => {
    // 遍历AST节点,匹配自定义的:::tabs和:::tab块
    // 将其转换为包含tab标题、内容的数组结构
  };
}

3. 编写Next.js的Tabs交互组件

在Next.js中写客户端组件处理切换逻辑(Next.js 13+ App Router需加'use client'):

// components/Tabs.js
'use client';
import { useState } from 'react';

export default function Tabs({ tabs }) {
  const [activeIndex, setActiveIndex] = useState(0);

  return (
    <div className="tabs-container">
      <div className="tab-bar">
        {tabs.map((tab, idx) => (
          <button
            key={idx}
            className={`tab-btn ${activeIndex === idx ? 'active' : ''}`}
            onClick={() => setActiveIndex(idx)}
          >
            {tab.title}
          </button>
        ))}
      </div>
      <div className="tab-content">
        {tabs[activeIndex].content}
      </div>
    </div>
  );
}

4. 复刻LeetCode的标签页样式

写CSS匹配LeetCode的视觉风格:

.tabs-container {
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  margin: 1.5rem 0;
  overflow: hidden;
}

.tab-bar {
  display: flex;
  background-color: #f9fafb;
  border-bottom: 1px solid #e5e7eb;
}

.tab-btn {
  padding: 0.75rem 1.25rem;
  border: none;
  background: transparent;
  cursor: pointer;
  font-size: 1rem;
  color: #4b5563;
  transition: all 0.2s;
}

.tab-btn:hover {
  background-color: #f3f4f6;
}

.tab-btn.active {
  border-bottom: 2px solid #3b82f6;
  color: #3b82f6;
  font-weight: 500;
  background-color: #fff;
}

.tab-content {
  padding: 1.25rem;
  background-color: #fff;
}

5. 整合到博客渲染流程

在Next.js博客页面中,将处理后的Markdown数据与Tabs组件结合:

  • 若用静态生成(SSG),在getStaticProps中用unified调用自定义插件解析Markdown,把tabs数据传给页面组件
  • 若用MDX,更简单:直接在Markdown里导入Tabs组件,像使用React组件一样调用,MDX会自动处理渲染

替代方案:用现成插件省事儿

不想自己写解析插件的话,可直接用remark-tabs这类现成库,或用MDX——MDX允许在Markdown中直接写React组件,灵活性更高,示例:

import Tabs from '../components/Tabs';

<Tabs tabs={[
  { title: '题目描述', content: <p>给定一个整数数组 nums 和一个整数目标值 target...</p> },
  { title: '代码实现', content: <pre><code className="language-javascript">function twoSum(...)</code></pre> }
]} />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 03:53:17