关于vuepress:手拉手基于vuepress2搭建专属自己的博客并集成评论打赏搜索等常用功能

博客地址

前言

两年前,我弃用了原来的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"
/>

咱们次要说一下reporepoIdcategorycategoryId怎么去取得:

首先进入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的插件在开发环境好使,打包的时候就报错,我也是踩了很多坑,以至于好几次想放弃,保持到最初才勉勉强强的搭建实现,所以有什么问题欢送在评论区点赞+探讨,让咱们动起手来共建博客吧

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理