.mdx
后缀的文件通常是一个MDX格式,MDX文件是Markdown for the component era
(组件时代的 Markdown)。它允许你在传统的 Markdown 文档中无缝地嵌入和渲染 JSX 组件(React, Vue, Preact, Solid 等),从而极大地扩展了 Markdown 的表现力和交互性。
1. 基本概念
1.1. 什么是 MDX?
简单的来说:MDX = Markdown + JSX。它是一种强大的文件格式,它让你可以在 Markdown 中:
- 使用 React 组件
- 嵌入 JSX 语法
- 执行 JavaScript 表达式
- 创建交互式内容
1.2. 文件扩展名
.mdx
:MDX 文件
.md
:传统 Markdown 文件(Docusaurus 也支持)
2. 基础语法
2.1. Front Matter 元数据
1 2 3 4 5 6 7
| --- title: MDX 教程 description: 学习如何使用 MDX 文件 sidebar_position: 1 tags: [mdx, react, docusaurus] date: 2024-01-15 ---
|
2.2. 基本 Markdown 语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| # 一级标题
这是段落文本。
## 二级标题
- 列表项 1 - 列表项 2 - 列表项 3
**粗体文本** *斜体文本* ~~删除线~~
[链接文本](https://example.com)

|
2.3. 代码块
1 2 3 4 5 6 7 8 9 10 11 12
| ```jsx // JavaScript/JSX 代码块 function Hello() { return <h1>Hello, World!</h1>; } ```
```python # Python 代码块 def hello(): print("Hello, World!") ```
|
3. JSX 集成功能
3.1. 内联 JSX
1 2 3 4 5
| # 内联 JSX 示例
这是一个段落,我可以直接使用 <span style={{color: 'red'}}>红色文本</span>。
也可以使用组件:<Button variant="outline">点击我</Button>
|
3.2. 导入和使用组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| --- title: 组件示例 ---
import Button from '@site/src/components/Button'; import Chart from '@site/src/components/Chart'; import { useState } from 'react';
# 使用 React 组件
## 静态组件
<Button onClick={() => alert('点击!')}> 点击按钮 </Button>
## 交互式组件
function Counter() { const [count, setCount] = useState(0); return ( <div> <p>计数: {count}</p> <button onClick={() => setCount(count + 1)}> 增加 </button> </div> ); }
<Counter />
|
3.3. 使用主题组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock';
# Docusaurus 主题组件
<Tabs> <TabItem value="js" label="JavaScript"> <CodeBlock language="javascript"> console.log('Hello JavaScript'); </CodeBlock> </TabItem> <TabItem value="py" label="Python"> <CodeBlock language="python"> print('Hello Python') </CodeBlock> </TabItem> </Tabs>
|
4. 高级功能
4.1. 自定义布局
1 2 3 4 5 6 7 8 9 10
| --- title: 自定义布局 layout: specialLayout ---
import SpecialLayout from '@site/src/components/SpecialLayout';
# 自定义页面
这个页面使用特殊的布局组件。
|
4.2. 条件渲染
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import { useThemeConfig } from '@docusaurus/theme-common';
# 条件内容示例
function ThemeAwareContent() { const { isDarkTheme } = useThemeConfig(); return ( <div> {isDarkTheme ? ( <p>当前是深色主题</p> ) : ( <p>当前是浅色主题</p> )} </div> ); }
<ThemeAwareContent />
|
4.3. 动态内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| --- title: 动态内容 ---
import { useEffect, useState } from 'react';
# 实时数据示例
function LiveData() { const [time, setTime] = useState(new Date().toLocaleTimeString()); useEffect(() => { const timer = setInterval(() => { setTime(new Date().toLocaleTimeString()); }, 1000); return () => clearInterval(timer); }, []); return ( <div style={{padding: '20px', background: '#f5f5f5'}}> <h3>当前时间: {time}</h3> </div> ); }
<LiveData />
|
5. 实际应用示例
5.1. 技术文档页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| --- title: React Hooks 教程 description: 学习 React Hooks 的使用方法 tags: [react, hooks, javascript] ---
import CodeBlock from '@theme/CodeBlock'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
# React Hooks 指南
## useState Hook
`useState` 是 React 中最常用的 Hook 之一。
<Tabs> <TabItem value="example" label="示例"> <CodeBlock language="jsx"> {`function Counter() { const [count, setCount] = useState(0); return ( <div> <p>计数: {count}</p> <button onClick={() => setCount(count + 1)}> 增加 </button> </div> ); }`} </CodeBlock> </TabItem> <TabItem value="live" label="实时演示"> <LiveCounter /> </TabItem> </Tabs>
## 互动演示
function LiveCounter() { const [count, setCount] = useState(0); return ( <div style={{padding: '20px', border: '1px solid #ddd'}}> <h3>实时计数器: {count}</h3> <button onClick={() => setCount(count + 1)} style={{marginRight: '10px'}} > + </button> <button onClick={() => setCount(count - 1)}> - </button> </div> ); }
<LiveCounter />
|
5.2. 产品特性页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| --- title: 产品特性 layout: features ---
import FeatureCard from '@site/src/components/FeatureCard';
# 我们的产品特性
## 核心功能
<div className="row"> <div className="col col--4"> <FeatureCard title="高性能" description="极快的处理速度" icon="🚀" /> </div> <div className="col col--4"> <FeatureCard title="安全可靠" description="企业级安全保障" icon="🔒" /> </div> <div className="col col--4"> <FeatureCard title="易于使用" description="直观的用户界面" icon="🎯" /> </div> </div>
## 实时数据展示
<LiveMetrics />
|
6. 最佳实践
6.1. 组件组织
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| --- title: 最佳实践 ---
// 在文件顶部导入所有组件 import Button from '@site/src/components/Button'; import Chart from '@site/src/components/Chart'; import { useState, useEffect } from 'react';
// 定义组件函数 function InteractiveDemo() { // 组件逻辑 return <div>演示内容</div>; }
# 内容标题
<InteractiveDemo />
|
6.2. 样式管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| --- title: 样式示例 ---
import './custom-styles.css';
# 自定义样式
<div className="custom-container"> <p className="highlight">突出显示的内容</p> </div>
<style>{` .custom-container { padding: 20px; background: #f0f8ff; border-radius: 8px; } .highlight { color: #ff6b6b; font-weight: bold; } `}</style>
|
6.3. 错误处理
1 2 3 4 5 6 7 8 9 10 11
| --- title: 错误边界 ---
import ErrorBoundary from '@site/src/components/ErrorBoundary';
# 安全组件渲染
<ErrorBoundary fallback={<p>组件加载失败</p>}> <PotentiallyFailingComponent /> </ErrorBoundary>
|
7. 与普通 Markdown 的区别
特性 |
Markdown (.md) |
MDX (.mdx) |
React 组件 |
❌ 不支持 |
✅ 完全支持 |
JSX 语法 |
❌ 不支持 |
✅ 完全支持 |
JavaScript 表达式 |
❌ 不支持 |
✅ 支持 |
交互式内容 |
❌ 有限 |
✅ 丰富 |
动态导入 |
❌ 不支持 |
✅ 支持 |
状态管理 |
❌ 不支持 |
✅ 支持 |
8. 调试技巧
8.1. 使用 console.log
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| --- title: 调试示例 ---
import { useEffect } from 'react';
# 调试 MDX
function DebugComponent() { useEffect(() => { console.log('组件已挂载'); }, []); return <div>检查控制台输出</div>; }
<DebugComponent />
|
8.2. 错误边界
1 2 3 4 5
| import ErrorBoundary from '@docusaurus/ErrorBoundary';
<ErrorBoundary> <YourComponent /> </ErrorBoundary>
|
应用场景
文档网站
这是 MDX 最流行的应用场景。
常见的支持MDX的文档网站框架:
- Docusaurus
- Next.js
- Gatsby
- Astro
常见的使用示例:
- 在 API 文档中嵌入一个可交互的参数演示。
- 在教程中嵌入一个可以实时编辑和预览的代码沙盒(如 CodeSandbox 或 StackBlitz 组件)。
技术博客
博主可以为自己的文章添加独特的交互式元素,提升阅读体验。
常见的支持MDX的博客网站框架:
产品营销页面
在介绍产品特性时,嵌入真实的产品 UI 组件,而不是静态图片。
教育课件
创建包含交互式测验、动画演示的课件。