跳到主要内容

MDX和React

MD 和 MDX 解析器

默认情况下,Docusaurus 使用 MDX 解析器,将 .md | .mdx 都是视为 MDX 文档。MDX 可视为 Markdown 的拓展集,允许在文档中使用 Markdown 和 JSX 语句。

mdx
# 这是一个 MDX 文件

常规的 **Markdown** 内容。

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

以上示例中 <div>...</div> 被视为 JSX ,标签之外的内容被视为 Markdown。JSX 语句在 Docusaurus 执行 npm run startnpm run build 时,被解析器转换为 React 语句,React 语句被转换为 HTML、CSS、JavaScript 最终被浏览器执行和渲染:

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

使用 MDX 需要一定的前端基础

使用 MDX 需要一定的前端基础:HTML、CSS、JavaScript、React。

Docusaurus 内置组件

Docusaurus 在 Markdown/MDX 中提供了许多内置 React 组件,你可以在文档中直接写 JSX 来使用这些组件。

Admonitions 提示框

被渲染为:

提示

这是一个提示

信息

这是信息

注意

这是警告

危险

这是危险

Tabs 选项卡

被渲染为:

bash
npm install

CodeBlock 高亮代码块

如何使用高亮代码块
如何使用高亮代码块

mdx
:::tip
这是一个提示
:::

:::info
这是信息
:::

:::warning
这是警告
:::

:::danger
这是危险
:::

被渲染为:

bash
zxzsk@debian ~> ls
appimage/ Arduino/ documents/ pictures/ script/ tmp/
Applications/ demo.js download/ project/ SiYuan/ videos/
apps/ desktop/ music/ public/ templates/

Details 折叠块

mdx
<details>
<summary>点我展开</summary>
这里是内容
</details>

被渲染为:

Details

点我展开 这里是内容

Head/Html 标签

mdx
import Head from '@docusaurus/Head';

<Head>
<title>自定义标题</title>
<meta name="keywords" content="docusaurus, mdx" />
</Head>

被渲染为:

ThemedImage 按主题切换图片

mdx
import ThemedImage from '@theme/ThemedImage';

<ThemedImage
alt="Docusaurus logo"
sources={{
light: '/img/logo-light.svg',
dark: '/img/logo-dark.svg',
}}
/>

被渲染为:

Docusaurus logoDocusaurus logo

要不要使用组件

直接在 Markdown 中使用组件或者 JSX 语法不是一个好主意,Markdown编辑器不能正确的渲染它们。

remark 插件

tip

如果你打算深入使用 Docusaurus, 可以编写自己的 remark 插件,比如在 Obsidian 中写一个代码块,指定一个格式,比如 makmap ,然后用 remark 插件在 Docusaurus 编译阶段,将代码块转换为需要的组件或 React 语法。

使用 React 组件

导入自定义组件

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

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

点击这个按钮:

使用 Docusaurus 内置组件

mdx
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 代码示例。

动态内容

嵌入可交互组件

mdx
import { useState } from 'react';

计数器示例:

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

<Counter />

计数器示例:

动态加载数据

mdx
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 />

复用内容

导入其他 MDX 片段

mdx
import PartialContent from './_partial.mdx';

复用内容示例:

<PartialContent />

复用组件逻辑

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

工具提示示例:

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

自定义布局

mdx
import Layout from '@theme/Layout';

自定义页面:

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

自定义页面:

这是自定义布局的内容

在线知识库

结合 Markdown 语法

mdx
混合 Markdown 和 JSX:

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

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

混合 Markdown 和 JSX:

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

完整示例

mdx
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!');

注意事项

  1. 组件作用域

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

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

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

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

更多学习资料: