跳到主要内容

mdx的使用建议

个人观点:少用 MDX 格式,因为缺少很好的 MDX 编辑器。MDX 的最终展示效果虽然经验,但编辑过程十分别扭(所见非所得),效率低下。

一、MDX 和 MD 混合模式

默认情况,Docusaurus 使用 MDX 解析器解析所有文章,我们可以修改配置让 Docusaurus 根据文档的后缀选择解析器:

docusaurus.config.js
markdown: {
// 可以设置为 md | mdx | detect
format: 'detect',
},
选项文档后缀 .md文档后缀 .mdx
mdx(默认)MDXMDX
mdMarkdownMarkdown
detect(推荐)MarkdownMDX

detect 对 Markdown 更加友好。

二、快速上手 Docusaurus 中 MDX

2.1 基础语法

MDX 允许在 Markdown 中直接混合 JSX 语法。

# 这是一个 MDX 文件

常规的 **Markdown** 内容。

<div style={{ padding: 20, background: '#868988' }}>
这是嵌入的 JSX 代码块,可以设置 CSS 样式。
</div>

这是嵌入的 JSX 代码块,可以设置 CSS 样式。

2.2 使用 React 组件

a. 导入自定义组件

import MyButton from '@site/src/components/MyButton';

点击这个按钮:<MyButton>提交</MyButton>

点击这个按钮:

b. 使用 Docusaurus 内置组件

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

## 选项卡示例

<Tabs>
<TabItem value="js" label="JavaScript">
这里是 JavaScript 代码示例。
</TabItem>
<TabItem value="py" label="Python">
这里是 Python 代码示例。
</TabItem>
</Tabs>

这里是 JavaScript 代码示例。

2.3 动态内容

a. 嵌入可交互组件

import { useState } from 'react';

计数器示例:

export function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
点击次数:{count}
</button>
);
}

<Counter />

计数器示例:

b. 动态加载数据

import { useState, useEffect  } from 'react';

API 数据示例:

export function UserData() {
const [data, setData] = useState(null);

useEffect(() => {
fetch('https://api.example.com/users')
.then(res => res.json())
.then(setData);
}, []);

return (
<div>
{data ? <pre>{JSON.stringify(data, null, 2)}</pre> : '加载中...'}
</div>
);
}

<UserData />

2.4 复用内容

a. 导入其他 MDX 片段

import PartialContent from './_partial.mdx';

复用内容示例:

<PartialContent />

b. 复用组件逻辑

import { MyTooltip } from '@site/src/components/Utils';

工具提示示例:

<MyTooltip text="这是一个提示">悬停此处</MyTooltip>

2.5 自定义布局

import Layout from '@theme/Layout';

自定义页面:

<Layout title="首页" description="欢迎来到我的网站">
<div className="custom-page">
<h6>这是自定义布局的内容</h6>
<p>在线知识库</p>
</div>
</Layout>

自定义页面:

这是自定义布局的内容

在线知识库

2.6 结合 Markdown 语法

混合 Markdown 和 JSX:

- **列表项 1**: <MyComponent />
- **列表项 2**: <span style={{ color: 'red' }}>红色文字</span>

| 列1 | 列2 |
|----------|------------|
| 单元格1 | <MyIcon /> |

混合 Markdown 和 JSX:

  • 列表项 1:
  • 列表项 2: 红色文字
列 1列 2
单元格 1

2.7 完整示例

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';


这是一个结合多种功能的示例:

<Tabs>
<TabItem value="code" label="代码示例">
<CodeBlock language="js">
console.log('Hello MDX!');
</CodeBlock>
</TabItem>
<TabItem value="demo" label="交互演示">
<button onClick={() => alert('点击成功!')}>点击我</button>
</TabItem>
</Tabs>

这是一个结合多种功能的示例:

console.log('Hello MDX!');

2.8 注意事项

  1. 组件作用域

    • 全局组件可在 docusaurus.config.js 中通过 themeConfig 配置自动导入。
    • 局部组件需手动 import
  2. 客户端交互性

    • 动态组件(如 useState)会生成客户端 JavaScript,可能导致页面体积增大。
  3. 性能优化

    • 复杂组件建议使用 <BrowserOnly> 包裹,避免服务端渲染报错:
      import BrowserOnly from '@docusaurus/BrowserOnly';

      <BrowserOnly>
      {() => <YourDynamicComponent />}
      </BrowserOnly>

更多学习资料: