MDX 实战:往博客里塞一个宝可梦图鉴
有一天我突然想在博客文章里放一个可以交互的宝可梦图鉴。
正常人会想:这不可能,Markdown 就是纯文本。
然后我发现了 MDX。
MDX 是什么
MDX = Markdown + JSX。
简单说,就是你可以在 .mdx 文件里直接写 React 组件,就像这样:
# 这是一篇普通的文章
正文内容...
<MyComponent client:load />
继续写文章...剩下的交给 Astro 处理。它会把 Markdown 渲染成 HTML,把 React 组件 hydrate 成可交互的 island。
先看效果
我写了一个图鉴组件,然后在这里调用它:
import Pokedex from '../../../components/Pokedex';
<Pokedex client:load />就这两行。然后经过我们的一点点修改 ——
Pokédex
支持中英日西四语言搜索、18 种属性筛选、防抖动态查询、分页。
(“一点点”)
client:load 是什么意思
Astro 默认不运行任何客户端 JS。要让 React 组件真正活起来,需要加一个 hydration 指令:
| 指令 | 时机 | 适用场景 |
|---|---|---|
client:load | 页面加载时立即 | 需要马上交互(比如图鉴) |
client:idle | 浏览器空闲时 | 不紧急的小组件 |
client:visible | 进入视口时 | 页面下方的组件 |
client:only="react" | 仅客户端,跳过 SSR | 依赖浏览器 API 的组件 |
图鉴需要一加载就开始请求数据,所以用 client:load。
import 路径有个坑
MDX 里的 import 要用相对路径,不能用路径别名:
✅ import Pokedex from '../../../components/Pokedex';❌ import Pokedex from '@/components/Pokedex';Astro 会在构建时解析 MDX,别名在这个阶段不一定能用。多打几个 ../ 就好了,又不是不能用。
小结
MDX 的核心就一句话:在 Markdown 里写 React,在 React 里写 Markdown。
至于图鉴里的 PokeAPI GraphQL 调用、多语言映射、防抖搜索……那些都是”一点点修改”,不重要。
重要的是,现在我的博客文章里有一个宝可梦图鉴了。
这才是最重要的事情。