MDX 和 React
Docusaurus 内置了对MDX v2的支持,它允许你在 Markdown 文件中编写 JSX,并将它们呈现为 React 组件。
查看MDX 文档,看看可以用 MDX 做什么奇特的事情。
MDX 格式非常严格,可能会出现编译错误。
使用**MDX playground**来调试它们并确保语法有效。
导出组件
要在 MDX 文件中定义任何自定义组件,必须导出它:只有以export
开头的段落才会被解析为组件,而不是散文。
export const Highlight = ({children, color}) => (
<span
style={{
backgroundColor: color,
borderRadius: '2px',
color: '#fff',
padding: '0.2rem',
}}>
{children}
</span>
);
<Highlight color="#25c2a0">Docusaurus green</Highlight> and <Highlight color="#1877F2">Facebook blue</Highlight> are my favorite colors.
I can write **Markdown** alongside my _JSX_!
注意它是如何呈现 React 组件中的标记和 Markdown 语法的:
I can write Markdown alongside my JSX!
因为所有的文档文件都是使用 MDX 解析的,所以任何看起来像 HTML 的东西实际上都是 JSX。因此,如果您需要内联样式组件,请遵循 JSX 风格并提供样式对象。
/* Instead of this: */
<span style="background-color: red">Foo</span>
/* Use this: */
<span style={{backgroundColor: 'red'}}>Foo</span>
导入组件
你也可以导入在其他文件中定义的自己的组件,或者通过 npm 安装的第三方组件。
<!-- Docusaurus theme component -->
import TOCInline from '@theme/TOCInline';
<!-- External component -->
import Button from '@mui/material/Button';
<!-- Custom component -->
import BrowserWindow from '@site/src/components/BrowserWindow';
虽然在 Markdown 中声明组件对于简单的情况非常方便,但由于编辑器支持有限、存在解析错误的风险以及低可重用性,它变得难以维护。当你的组件涉及复杂的 JS 逻辑时,使用一个单独的.js
文件:
import React from "react";
export default function Highlight({ children, color }) {
return (
<span
style={{
backgroundColor: color,
borderRadius: "2px",
color: "#fff",
padding: "0.2rem",
}}
>
{children}
</span>
);
}
import Highlight from '@site/src/components/Highlight';
<Highlight color="#25c2a0">Docusaurus green</Highlight>
如果在许多文件中使用相同的组件,则不需要在所有地方导入它——考虑将它添加到全局作用域。见下文
MDX 组件范围
除了导入组件和导出组件之外,在 MDX 中使用组件的第三种方法是将它注册到全局作用域,这将使它在每个 MDX 文件中自动可用,而不需要任何导入语句。
例如,给定这个 MDX 文件:
- a
- list!
And some <Highlight>custom markup</Highlight>...
它将被编译成一个包含ul
, li
, p
, 和 Highlight
元素的 React 组件。Highlight
不是一个原生的 html 元素:你需要为它提供你自己的 React 组件实现。
在 Docusaurus 中,MDX 组件作用域由@theme/MDXComponents
文件提供。它不是一个 React 组件,per se,不像其他大多数在@theme/
别名下的导出:它是一个从标签名(如Highlight
)到它们的 React 组件实现的记录。
如果你swizzle这个组件,你会发现所有已经实现的标签,你可以通过 swizzling 各自的子组件来进一步定制我们的实现,比如@theme/MDXComponents/Code
(用于呈现Markdown 代码块)。
如果你想注册额外的标签名称(像上面的<Highlight>
标签),你应该考虑包装@theme/MDXComponents
,这样你就不必维护所有现有的映射。由于 swizzle CLI 不允许包装非组件文件,你应该手动创建包装器:
import React from "react";
// Import the original mapper
import MDXComponents from "@theme-original/MDXComponents";
import Highlight from "@site/src/components/Highlight";
export default {
// Re-use the default mapping
...MDXComponents,
// Map the "<Highlight>" tag to our Highlight component
// `Highlight` will receive all props that were passed to `<Highlight>` in MDX
Highlight,
};
现在,您可以在每个页面中自由地使用<Highlight>
,而无需编写 import 语句:
I can conveniently use <Highlight color="#25c2a0">Docusaurus green</Highlight> everywhere!
I can conveniently use Docusaurus green everywhere!
我们故意使用像Highlight
这样的大写标签名称。
从 MDX v2+开始(Docusaurus v3+),小写标记名总是呈现为原生 html 元素,并且不会使用您提供的任何组件映射。
此功能由一个MDXProvider
提供支持。如果你要在 React 页面中导入 Markdown,你必须自己通过MDXContent
主题组件提供这个提供者。
import React from "react";
import FeatureDisplay from "./_featureDisplay.mdx";
import MDXContent from "@theme/MDXContent";
export default function LandingPage() {
return (
<div>
<MDXContent>
<FeatureDisplay />
</MDXContent>
</div>
);
}
如果您没有将导入的 MDX 包装为MDXContent
,则全局作用域将不可用。