博客地址
前言
两年前,我弃用了原来的 hexo 博客零碎,并用 vuepress1.4.1 版本疾速搭建了本人当初的专属动态博客零碎。并始终更新保护至今。博客内陆陆续续的定制了本人的共性首页和列表页,扩大了评论、footer、复制、图片预览等等博客常见性能,成果和 UI 实现还是让我比较满意的。然而自从 vuepress 降级到 2.X 后,就始终心动的想要将现有博客进行降级,奈何平时比较忙(懒癌早期),所以始终没有付诸行动,最近闲下来,所有打算动起来。
这次尽管是从新从零搭建,但其实很多逻辑和 1.0 是相通的,所以我的博客 1.0 还是能够用来参考的,如果你也是 vuepress1.X 版本,也能够参考官网的迁徙文档
VuePress2 的亮点
- 简介至上
- 反对 vue3.0,就是好用。
- 反对 typescript,学习、开发必备技能。
- vite 打包,就是快。
-
多语言反对
VuePress 和其它博客零碎的比照能够参看官网给出的介绍
我的项目搭建
我的项目创立 & 初始化
# 创立并进入博客文件
mkdir vuepress-blog
cd vuepress-blog
# 初始化 git
yarn init
# 装置 vuepress 本地依赖
yarn add -D [email protected]
# 增加 ignore 内容
echo 'node_modules' >> .gitignore
echo '.temp' >> .gitignore
echo '.cache' >> .gitignore
# 增加第一个 md 文档
mkdir docs
echo '# Hello VuePress' > docs/index.md
在 package.json
中增加一些 scripts
{
"scripts": {
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs"
}
}
命令行内运行上面代码,就能够顺利的启动一个热重载的博客我的项目了
yarn docs:dev
搭建首页
vuepress 容许咱们依赖 Frontmatter->layout
来自定义页面布局;上面说一下首页
-
docs/.vuepress/Layouts
文件内新建Home.vue
文件,因为自定义的页面说白了也是一个组件,所以咱们能够依照平时写 vue3 组件的形式去写首页内容<template> <view> 首页 </view> </template>
-
在
docs/.vuepress/client.ts
文件中注册 Home 组件import {defineClientConfig} from '@vuepress/client' import Home from './Layouts/Home.vue' export default defineClientConfig({ layouts: {Home,} })
-
在一开始创立的
docs/index.md
文件内,讲自定义布局组件进行引入--- title: 首页 layout: Home ---
到这咱们的首页就生成好了,还是比较简单的对吧,别急,上面的列表页才是最简单的中央
列表页面
列表页最要害的就是要如何能力拿到所有文章的数据内容,这里咱们依赖官网的插件 API 来实现
因为咱们须要创立很多 md 文件,然而并不一定所有的文件都须要显示在列表页,所以咱们首先要约定下什么格局的文件才是咱们须要的博客文档:咱们能够设置黑名单来进行排除,当然我这里用的正则匹配的形式,即 https://slbyml.github.io/**/**
是咱们须要的博客文件,否则就是其余文件,不进行统计,比方:https://slbyml.github.io/
、https://slbyml.github.io/*.html
第一步:创立插件文件.vuepress/plugins/page.js
:
export default {
name: 'vuepress-plugin-page',
onInitialized(app) {const lists = []
app.pages.forEach((item:Page) => {
// 排除不须要的页面
if (/^\/[\s\S]*\/[\s\S]*/.test(item.path)) {
// 没有间接将整个 item 放进 lists 是为了缩小传递大量没用的数据
lists.push({
path: item.data.path,
title: item.data.title,
frontmatter: item.data.frontmatter,
git: item.data.git
})
}
// 将咱们组装好的列表传递到 list 页面
if (item.path === '/list.html') {
item.data = {
...item.data,
lists
}
}
});
// 这里还须要进行下简略的排序
lists.sort((s1, s2) => {return +new Date(s2.git.lastUpdated) - +new Date(s1.git.lastUpdated)
})
}
}
当然,向列表页传递数据也能够参考官网给的计划:向客户端代码传递数据
第二步:创立自定义列表布局.vuepress/Layouts/List.vue
<template>
<Navbar />
<div class="contain">
<div class="lists" v-for="item in lists" :key="item.path">
<a :href="item.path" class="link" :title="item.title">{{item.title}}</a>
<div> {{item.frontmatter.description}}</div>
</div>
</div>
</template>
<script>
import {usePageData} from '@vuepress/client'
import Navbar from '@theme/Navbar.vue'
import {ref} from 'vue'
export default {
components: {Navbar // 官网原生的 header, 能够间接拿来用},
setup() {const page = usePageData()
const allList = ref(page.value.lists || []) // 咱们在上一步传递进来的所有文章列表
return {allList}
}
}
</script>
<style lang="scss" scoped></style>
第三步:注册列表布局.vuepress/client.ts
import {defineClientConfig} from '@vuepress/client'
import Home from './Layouts/Home.vue'
import List from './Layouts/List.vue'
export default defineClientConfig({
layouts: {
Home,
List
}
})
第四步:创立列表文件docs/list.md
,将咱们的自定义布局引入进去
---
title: 文章列表
layout: List
---
至此咱们最重要的首页和列表页就实现了
文章标签收集
先来看看我文章内 frontmatter
最重要的两个
---
tags:
- vuepress
- 前端
description: 文章的形容信息,---
description
:文章自定义的形容信息,在列表页内item.frontmatter.description
办法能够拿到-
tags
就是咱们文章的自定义标签,通过frontmatter.tags
就能够取得了,我是在列表页用到的const allTags = allList.value.reduce((previous, current) => {return previous.concat(current.frontmatter.tags) }, [])
分页
咱们既然能够拿到所有的文章列表的数组,那么咱们就能够通过 allList
来自定义咱们的分页逻辑了,还是比较简单的,对吧!
文章页用扩大的默认布局
具体文章页如果只须要官网默认的布局那能够不看这部分内容,我做的事件次要是继承了官网默认布局,并扩大了浏览进度、评论、打赏、footer 等性能;
创立 .vuepress/layouts/Layout.vue
<template>
<ParentLayout>
<template #page-content-bottom>
<div class="money"> 打赏 </div>
<div> 评论 </div>
</div>
</template>
<template #page-bottom>footer</template>
</ParentLayout>
</template>
<script>
import ParentLayout from '@vuepress/theme-default/layouts/Layout.vue'
export default {
components: {ParentLayout}
}
</script>
增加默认布局组件.vuepress/client.ts
import {defineClientConfig} from '@vuepress/client'
import Layout from './Layouts/Layout.vue'
export default defineClientConfig({
layouts: {Layout}
})
好了,实现这一步后,咱们所有文章页都会应用这个布局形式来渲染。
察看组建能够发现咱们都是通过插槽来实现的扩大,更多布局插槽能够参考官网继承,置信聪慧的博友应该能过痛过它实现更有意思的货色
增加 Giscus 评论
评论是一个博客的灵魂,为博客提供了互动的能力,上一版博客我是用的 GITALK 来实现的,它是基于 issue
来实现的,所以它有一些不好的中央让我不是很称心,比方:评论无奈叠楼层、须要博主先登录文章页去初始化评论性能,所以这次我决定改用基于 Github Discussions
的 Giscus 来实现;当然,如果你仍然对 GITALK
情有独钟,能够参考这篇文章。
通过上一步的布局扩大发现,咱们能够将评论组件搁置在 #page-content-bottom
插槽内,Giscus
贴心的问咱们提供了各种罕用的援用形式:Vue 组件
、React 组件
、web component
等形式;咱们能够应用本人喜爱的形式进行装置援用。
<Giscus
repo="slbyml/slbyml.github.io"
repoId="R_kgDOH_OGFQ"
category="Announcements"
categoryId="DIC_kwDOH_OGFc4CRZwH"
mapping="specific"
reactionsEnabled="1"
emitMetadata="0"
inputPosition="top"
theme="light"
lang="zh-CN"
loading="lazy"
/>
咱们次要说一下 repo
、repoId
、category
、categoryId
怎么去取得:
首先进入 Giscus 官网,依照流程填写必要信息,留神仓库地址不要带 https,填写完后,上面就会生成必要信息,咱们间接在组件内替换对应的参数就能够了
增加自定义性能
一个残缺、共性、有意思的博客必定还会有很多自定义的 JS 内容要实现,比方 copy 主动增加版权、控制台默认输入定制 log、动静页面 title 等等;这些大部分都有第三方组件来帮助咱们实现这些货色,然而如果找不到咱们就须要本人去写,咱们以 copy 主动增加版权
为例(这个也有三方插件,能够自行搜寻):
新建文件.plugins/plugins/copy.js
export default () => {function addCopy(e) {
let copyTxt = ""
e.preventDefault(); // 勾销默认的复制事件
copyTxt = window.getSelection(0).toString()
copyTxt = `${copyTxt}\n 作者:静水深流 \n 原文:${window.location.href}\n 著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。`
// 将信息写入粘贴板
const clipboardData = e.clipboardData || window.clipboardData
clipboardData.setData('text', copyTxt);
}
document.addEventListener("cut", e => {addCopy(e)
});
document.addEventListener("copy", e => {addCopy(e)
});
}
批改 .vuepress/client.ts
文件:
import {defineClientConfig} from '@vuepress/client'
import copy from './plugins/copy'
export default defineClientConfig({async setup() {if(!__VUEPRESS_SSR__){ // 运行在客户端
copy()}
}
})
__VUEPRESS_SSR__
代表函数不运行在服务端(SSR)下;这个常量是 Vuepress 为咱们提供的,更多变量参考常量
草稿性能
很多时候咱们可能会同时写多篇笔记和文章,或者是写完后临时不想收回去,这个时候,就须要一个草稿箱来临时存储咱们的文章,以防影响发表别的文章,咱们有两种形式来实现
第一种就是批改 .vuepress/plugins/page.js
文件,通过在代码中过滤掉特定格局的文件来实现不讲文件链接往外裸露,这种形式间接的实现了草稿箱性能,然而如果晓得链接或者通过搜寻性能搜寻到了这个页面还是能够进去的
第二种也是我当初正在用的形式:通过官网提供的 pagePatterns
性能,它能够防止某个文件被 VuePress 解决,所以咱们能够通过这个性能来实现想要的成果,我是将所有下划线结尾的文件作为草稿文件的
批改.vuepress/config.ts
import {defineUserConfig} from 'vuepress'
export default defineUserConfig({pagePatterns:['**/*.md','!**/_*.md','!node_modules']
})
生成 sitemap
博客只有在他人可能搜寻的到才有更多创作的意义,因而咱们须要生成站点地图:sitemap
,它做 seo 必不可少的文件,首先装置装这个插件yarn add vuepress-plugin-sitemap2 -D
;而后批改.vuepress/config.ts
import {defineUserConfig} from 'vuepress'
import {sitemapPlugin} from "vuepress-plugin-sitemap2"
import {googleAnalyticsPlugin} from '@vuepress/plugin-google-analytics' // 做 google 收录 & 上报剖析用
export default defineUserConfig({
plugins: [
googleAnalyticsPlugin({id: 'google-analytics 生成的'}),
sitemapPlugin({hostname: 'https://slbyml.github.io'})
]
})
而后咱们就能够将生成的文件 https://slbyml.github.io/sitemap.xml
进行百度收录、谷歌收录、360、搜狗、Bing 等等能提交的都提交下
打包部署
我的源码文件和打包文件是离开来存储的,一个公有,一个公开。次要是因为源码中蕴含一些备注文件不太不便公开,因而为了不便,写了一个主动打包上传的办法,
#!/usr/bin/env sh
# 确保脚本抛出遇到的谬误
set -e
# 生成动态文件
yarn build
# 进入生成的文件夹
cd docs/.vuepress/dist
git init
git add -A
git commit -m 'blog'
git push -f [email protected]:slbyml/slbyml.github.io.git master
cd -
Package.json 中增加一个 script:·”deploy”: “bash deploy.sh”·,这样就能够通过 yarn deploy
一键操作了,还是比拟香的
前期布局
- [] 增加 docsearch
- [] 主动上传 CDN
情谊提醒
自行搜寻插件的时候,请看清楚反对的是 vuepress1.x
还是vuepress2.x
,当初很多插件还只是反对 1.x,且有些宣称反对 2.x 的插件在开发环境好使,打包的时候就报错,我也是踩了很多坑,以至于好几次想放弃,保持到最初才勉勉强强的搭建实现,所以有什么问题欢送在评论区点赞 + 探讨,让咱们动起手来共建博客吧