构建时加载数据,生成列表
我们可以在构建时加载,比如用于生成一个目录的列表。
参考文档见:https://vitepress.dev/guide/data-loading
生成 blog 目录
1. 编写加载函数 blog.data.ts
ts
// file: ./.vitepress/theme/blog.data.ts
import fs from 'node:fs'
export default {
watch: ['../../blog/*.md'],
load(watchedFiles) {
// watchedFiles will be an array of absolute paths of the matched files.
// generate an array of blog post metadata that can be used to render
// a list in the theme layout
return watchedFiles.map((file) => {
return fs.readFileSync(file, 'utf-8')
})
}
}
2. 在 blog.md 中使用
为避免 blog.md 放在 ./blog/
目录中也被载入,或需要剔除,我们将之放在 .
目录。
md
<script setup>
import { data as posts } from './.vitepress/theme/blog.data.ts'
console.log(posts)
</script>
<h1>All Blog Posts</h1>
<ul>
<li v-for="post of posts">
{{ post }}
</li>
</ul>
效果如下图所示:
使用 createContentLoader
我们还可以更便捷地使用 createContentLoader
来加载 .md 等数据。
例如,我们在 ./blog/
目录有如下文件:
blog
├── 20240401-vitepress-intro.md
├── 20240403-vitepress-howto.md
└── 20240410-vitepress-tutorial.md
其中每个文件有 frontmatter 如下:
md
---
title: 'vitepress tutorial'
author: 'VP'
---
1. 编写 loader
修改 blog.data.ts
为:
ts
// file: ./.vitepress/theme/blog.data.ts
import { createContentLoader } from 'vitepress'
export default createContentLoader('blog/*.md', /* options */)
2. 编写一个目录组件
vue
// file: ./.vitepress/theme/BlogHome.ts
<script setup>
import { data as posts } from './blog.data.ts'
</script>
<template>
<h1>All Blog Posts</h1>
<ul>
<li v-for="post of posts">
<a :href="post.url">{{ post.frontmatter.title }}</a>
<span>by {{ post.frontmatter.author }}</span>
</li>
</ul>
</template>
3.在 index.ts
中注册组件
ts
import BlogHome from './BlogHome.vue'
export default {
extends: DefaultTheme,
enhanceApp({ app, router, siteData }) {
app.component("BlogHome", BlogHome );
}
} satisfies Theme
4. 在页面中使用
我们在首页(index.md
)增加:
md
<div class='mt-20'>
<BlogHome />
</div>
你可以不全局注册组件(不做之前的第三步),而仅在需要时导入,如下:
md
<div class='mt-20'>
<BlogHome />
</div>
<script setup lang="ts">
import BlogHome from './.vitepress/theme/BlogHome.vue'
</script>
效果如下:
添加 "type":"module"
要能成功使用如下代码,需要对 package.json 进行调整,增加:
json
{
"type": "module",
"scripts": {
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
},
}
添加 "type": "module" 是为了让 Node.js 把 .js 文件当作 ESM 来处理。
否则会遇到错误 ERROR: [plugin: externalize-deps] "vitepress" resolved to an ESM file. ESM file cannot be loaded by
require. See https://vitejs.dev/guide/troubleshooting.html#this-package-is-esm-only for more details.