跳到主要内容

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 start 和 npm 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>

更多学习资料: