Markdown + VuePress 构建个人主页

分享一下自己的个人主页模板,用 Markdown 轻松地编辑与生成个人主页。
VuePress HomePage

项目初衷

很久之前就有打算做个人主页(Academic Portfolio/Online Resume)。感觉将来在学校申请、找工作等各方面都能够用上。
之前考虑过用纯 HTML 单页面静态文件来实现,但是这样 HTML 文件会变得非常长,之后增删信息也会变得麻烦。
大概在 2018 年 4 月,VuePress 出现了,起初它是用来管理项目文档的。它的好处之一是能够在 Markdown 文件中插入 Vue 的组件。可以利用这一点添加自定义的组件,然后用 VuePress 构建静态的网页文件。这是我目前个人觉得非常好的一套管理方式,并在 GitHub 上开源了我自己使用的模板 vuepress-homepage。之后可以在 GitHub Pages 或者 Netlify 实现免费的部署。

项目结构

整个项目的结构基本就是一个 VuePress 项目的结构,也是很经典的一个 Node 项目结构。所有的文档和配置都在 docs 文件夹中。在 .vuepress 文件夹里面,components 文件夹包含了我们自己实现的 Vue 组件,public 文件夹中是所有图片文件,style 文件夹下是一些独立的 CSS 样式,config.js 包含了 VuePress 的设置。
基本的使用可以参照项目中的每个文件,直接套用我的模板的话无非就是修改 Markdown 文件就行了。关于进一步的具体的使用及配置可以到 VuePress 官网查看其教程与配置说明,这里不再赘述。

项目部署

我个人的项目是用了 Netlify 进行部署。Netlify 部署起来非常简单,只要在它的网站上绑定一下 GitHub 的仓库,然后构建指令就是 yarn build,默认输出静态网站到 dist 文件夹。之后 Netlify 会自动 serve 这个文件夹中的静态网页。我们能够在 Netlify 中添加自定义子域名以及 Netlify 会自动添加 HTTPS 支持。

可以到 https://vuepress-homepage.netlify.com/ 查看部署好后的效果。

组件化的 Markdown

这里我具体解释对主页面 Markdown 文件的每部分我是如何设计和实现的。

以题图里的页面为例,About Me 以及 News 等部分都是直接 Markdown 输出的文字部分内容。因为整个页面比较简单,是比较自然的自上向下的结构,因此可以将最上面的部分视为一个可拔插的组件。
在 components 下用实现了 ProfileSection.vue 的组件,之后在 Markdown 文件里面就能够直接使用。对于名字、邮箱等参数的传递,我利用了 Markdown 的 frontmatter,本质上是 yaml,像简化版的 json。因为 VuePress 在解析 Markdown 时会有个全局的 frontmatter 变量,这样只需要将所有的参数放在 frontmatter 中,就能避免在正文组件里传递太多的参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
---
pageClass: home-page
# some data for the components

name: Harry Potter
profile: /profile.jpg

socials:
- title: github
icon: "/icons/github.svg"
link: https://github.com/mtobeiyf
- title: linkedin
icon: "/icons/linkedin-mono.svg"
link: https://www.linkedin.com
- title: instagram
icon: "/icons/instagram-mono.svg"
link: https://www.instagram.com

cv: https://en.wikipedia.org/wiki/Harry_Potter
bio: Student at Hogwarts School
email: harry (at) hogwarts (dot) edu
---

<ProfileSection :frontmatter="$page.frontmatter" />

上面的 pageClass 可以给当前 Markdown 文件渲染后的元素添加类。这样可以当前 Markdown 文件最后面添加自定义的 CSS 来修改样式。
对于每个 Project 的项目,我也制作了一个自定义的组件。

1
2
3
4
5
6
7
8
9
10
11
<ProjectCard image="/projects/1.png">

Harry P., Hermione G., *et al*

**The Making of Harry Potter's Wand**

Harry's wand was broken in 1997, but was repaired by him after the 1998 Battle of Hogwarts..

[[PDF](https://www.google.com)] [[arXiv](https://arxiv.org)]

</ProjectCard>

就能够渲染成下面的样式,其中包含在自定义组件之间的内容能够被捕捉,并在 .vue 组件中很方便的以 Slot 的形式去使用。