博客搭建 | 五 使用 vitepress
简述
最初,我的博客使用的vuepress搭建的,使用的是vuepress-theme-reco,功能齐全,布局简洁美观,也花了一些心思在搭建上面,后来reco主题进入2.x的开发中,1.x版本进入稳定版本,作为博客,内容才是关键,vuepress和它的主题都是载体,而在今年开始(也好像是去年),博客在actions中一直报错,大概是旧版本依赖被弃用了,导致博客无法正常更新至线上,所以便考虑升级博客。
reco2.x仍然采用vuepress作为驱动,而尤雨溪推出了vitepress之后,我决定拥抱新技术,在动手中了解新框架。虽然官方说vuepress和vitepress定位不同,没有替代一说,但vite带来的开发体验确实更好,随着文章的增多,vuepress的启动速度与打包速度都不及vitepress。
在这里提示大家,vitepress作为静态文档生成框架,在工作中接触到的无非是生产相关文档,不需要深入了解,所以也提示大家,如果非兴趣所致,不需要在这上面花太长时间。
本篇文章主要是在实践博客搭建中介绍vitepress的一些特性,目标是对reco主题的部分功能进行复刻。
初始化vitepress项目
pnpm add -D vitepress
pnpm vitepress init
安装和初始化后,我们会得到一个基本的项目框架,运行后会看到一个类似vitepress官方文档的页面布局。
项目目录
为了方便实现博客的一些功能,我们将自己的文章内容分为两类,一类是内容页,一类是功能页(文章列表,时间线等),所以在目录中新建 blogs
和page
两个文件夹,那么整体的目录结构为:
.
├─ .vitepress
│ ├─ theme // 主题相关
│ └─ config.mts // 项目配置
├─ blogs // 文章文件夹 // [!code ++]
├─ page // 功能页 // [!code ++]
├─ api-examples.md // 示例md
├─ markdown-examples.md // 示例md
└─ index.md // 示例md
└─ package.json
进行基础配置
.vitepress>config.mts
, 这是整个博客的配置文件,要显示什么,怎么显示都需要再其中设置,现在要对其进行基础设置
1. 汉化
// config.mts
export default {
// 应用级配置选项
lang: "zh", //中文配置
markdown: { // vitepress 对md进行了扩展,有些写法有特殊的样式
container: {
tipLabel: '提示',
warningLabel: '警告',
dangerLabel: '危险',
infoLabel: '简述',
detailsLabel: '详细信息'
}
},
themeConfig: { // 主题配置
lastUpdated: { // 更新时间的显示
text: '更新于',
formatOptions: {
dateStyle: 'medium',
timeStyle: 'medium'
}
},
search: { // 搜索
provider: "local",
options: {
translations: {
button: {
buttonText: "搜索文档",
buttonAriaLabel: "搜索文档",
},
modal: {
noResultsText: "无法找到相关结果",
resetButtonTitle: "清除查询条件",
footer: {
selectText: "选择",
navigateText: "切换",
},
},
},
},
},
notFound:{ // 404页
title: '未找到页面,迷路了~',
quote: '请检查地址是否正确,或当前页面未开通,点击下方按钮返回首页',
linkText: '返回首页'
},
}
}
汉化内容可以完全按照自己的想法去设置。
2. 导航
在vitepress中,如果项目不设置根目录和源目录,使用默认设置,那么与.vitepress
同级的目录为/
// config.mts
export default {
themeConfig: { // 主题配置
nav: [
{ text: "主页", link: "/" },
{ text: "分类", link: "/category.md" },
{ text: "标签", link: "/tag.md" },
{ text: "时间线", link: "/timeline.md" },
{ text: "留言板", link: "/messageBoard.md" },
],
}
}
自定义页面
一般在博客首页都会展示文章列表,为了展示相关内容,我们需要自定义一些页面
vitepress在编译时将md文档转成html,也允许我们在像正常的vue项目中使用组件。
这里以博客主页为例
1. 依赖安装
首先我们需要安装vue,其实我们不安装也可以直接使用,只不过编辑器会不断的报错,特别是在ts环境下,很多vue语法会报错,所以需要安装vue,如果在我们自定义中想要使用其他框架也是可以的,这个就见仁见智了。
2. 创建相关文件
.
├─ .vitepress
│ ├─ theme
│ | ├─ components
| | | ├─ Blog.vue // [!code ++]
| | | ├─ More... // [!code ++]
| | ├─ index.ts // 主题入口
| | ├─ posts.data.ts // [!code ++]
Blog.vue
是博客主页的vue文件,可以任意添加一些内容,后面再讲如何获取博客列表。
3. 引入组件
// .vitepress>theme>index.ts
import { h } from 'vue'
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import Blog from "./components/Blog.vue"; // [!code ++]
import './style.css'
export default {
extends: DefaultTheme,
Layout: () => {
return h(DefaultTheme.Layout, null, {
// https://vitepress.dev/guide/extending-default-theme#layout-slots
})
},
enhanceApp({ app, router, siteData }) {
// ...
app.component("blog", Blog); // [!code ++]
}
} satisfies Theme
引入代码没什么需要说明的,回头看一下默认初始化出来的index.md
中的内容,头部的配置了一些属性,vitepress会读取它们并执行相关操作,比如 layout:home
,该属性表明该页面是使用home
组件渲染页面,因此,当我们将layout:home
替换成layout:blog
,博客首页的渲染内容便成了你的组件内容。
官方提供了三种页面布局:doc | home | page
,你可以在 这里 查看他们的详情。
4. 文章列表组件
获取文章列表的方式vitepress也提供了,在第二步创建的posts.data.ts
,其内容可直接复制官方代码,这里是说明,大致了解一下就可以。
需要注意的有以下两点:
// posts.data.ts
export default createContentLoader('posts/*.md', { // [!code --]
export default createContentLoader('blogs/**/*.md', { // [!code ++]
excerpt: true,
transform(raw): Post[] {
return raw
.map(({ url, frontmatter, excerpt }) => ({
title: frontmatter.title,
url,
excerpt,
date: formatDate(frontmatter.date)
}))
.sort((a, b) => b.date.time - a.date.time)
}
})
在初始化时创建了两个目录,区分了文章和功能页,也是为了这里在获取文章列表时减少不必要的操作
考虑到后期要增加的标签、分类、时间线等功能,所以需魔改一下createContentLoader
,这里贴一下代码仅供参考。
::: details
export default createContentLoader("blogs/**/*.md", {
transform(raw): BlogData {
const blogData: BlogData = {
posts: [],
tags: [],
categories: [],
everyCategoryCount: {},
};
raw.forEach(({ url, frontmatter, excerpt }) => {
if (frontmatter.publish == undefined || frontmatter.publish) {
if (frontmatter.tags) blogData.tags.push(...frontmatter.tags);
if (frontmatter.categories) {
blogData.categories.push(...frontmatter.categories);
frontmatter.categories.forEach((category: string) => {
if (blogData.everyCategoryCount[category]) {
blogData.everyCategoryCount[category]++;
} else {
blogData.everyCategoryCount[category] = 1;
}
});
}
blogData.posts.push({
title: frontmatter.title,
url,
excerpt,
date: formatDate(frontmatter.date),
frontmatter,
});
}
});
blogData.tags = removeDuplicates(blogData.tags) as string[];
blogData.categories = removeDuplicates(blogData.categories) as string[];
blogData.posts.sort((a, b) => b.date.time - a.date.time);
return blogData;
},
});
:::
createContentLoader
将处理并返回文章数组,但使用时,并不需要调用该方法,直接使用导出的data
import { data } from '../posts.data'
// 文章数组
console.log(data.posts)
// 省略
基于此流程,便可以创建更多的自定义页面
5. 重写路由
当把所有的功能页(包括主页index.md)放进page
文件夹后,我们在导航配置的路由需要加上前缀/page/
,如果点击左上交标题,默认回到路由/
,以及在默认打开博客时,都是空白页,vitepress提供了路由的重写,这里我们需要重写page
的路由
// config.mts
export default {
rewrites: {
'page/(.*)': '(.*)',
},
}
需要注意的是,路由重写后,我们在nav
配置的地址应是重写后的
主题
vitepress定义了一些css变量,并且默认分为深色和浅色两个主题,如果想要自定义主题样式,可以在styles.css
中覆盖这些样式,官方css变量,
运行时API
VitePress 提供了几个内置的 API 来让你访问应用程序数据。VitePress 还附带了一些可以在全局范围内使用的内置组件。
useData
可访问到页面相关数据和config.mts
中自定义的属性,比如:
export default {
themeConfig:{
docCount:10, // [!code ++]
}
}
上述代码在主题配置中新增定义docCount
,这个属性是我用来配置文章列表分页的,然后这样使用:
import { useData } from 'vitepress'
const { theme } = useData()
const docCount: number = theme.value.docCount; // 每页展示文章数量
useRouter
路由示例,进行路由跳转
import { useRouter } from 'vitepress'
const { go } = useRouter()
<div @click="go('/somePageRoute')"></div>
<Content />
<Content />
组件显示渲染的 md 内容。
<!-- blog.vue -->
<template>
<h1>Custom Layout!</h1>
<content />
</template>
总结
通过上述流程,基本将vitepress可能用到的功能使用了一遍,当然还有很多没有讲(目前我还没用到..),感兴趣的可以用它创建自己的主题博客或知识笔记,目前我的博客正在搭建中,也欢迎访问~ 个人博客
转载自:https://juejin.cn/post/7380296428142477312