如何在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
相关产品推荐
相关产品推荐

