我用 Vuepress 搭了一个好看的博客

· sakamoto · Created at · Last by kkmmi68 Replied at · 2433 hits
96

博客支持功能

  • [x] 文章分类功能
  • [x] 打赏模块
  • [x] 按年归档
  • [x] 文章置顶
  • [x] 文章创建时间支持
  • [x] 文章阅读量统计与评论
  • [x] 更好的移动端阅读效果
  • [x] RSS订阅
  • [x] 文章设置密码

开发环境

本博客的开源代码地址

效果预览

开始

具体的开发细节官网上已经说得很详细了,而且代码已经开源,所以这里不在说具体的细节,主要列举开发过程中遇到的一些问题。

如何添加分类的路由

只需要在 enhanceApp.js 中获取 Vue 以及 router 这两个对象,然后像在开发Vue项目中给应用添加正常的路由即可。

代码如下:

const CategoryLayout = () => import('@theme/layouts/CategoryLayout')

const CATEGORYPATH = '/category/'

const install = (Vue, { router }) => {
  let routes = []
  routes.push({
    path: `${CATEGORYPATH}:category?`,
    component: CategoryLayout,
    meta: { tag: true }
  })
  router.addRoutes(routes)
}

export default { install }

文章创建时间支持

VuePress 默认是没有文章的创建时间这个字段的,其实实现这个功能也比较简单,就是通过 Vuepress 提供的 Plugin 的功能。

需要知道的是, vuepress 中的 plugin 是运行在 node 的环境中的。所以只需要,利用 node 提供的 fs.statSync 这个api即可。

具体代码如下:

const fs = require('fs')

module.exports = (options = {}, context) => ({
  extendPageData ($page) {
    $page.publishDate = getFilePublishDate($page._filePath)
  }
})

function getFilePublishDate (filePath) {
  let publishDate
  try {
    publishDate = fs.statSync(filePath).birthtime
  } catch (e) { /* do not handle for now */ }
  return publishDate
}

只需要在 vuepress 的 config.js 中加载这个plugin即可。
javascript
···
plugins: [
require('./plugins/page-publish-date.js')
],
···

文章阅读量统计与评论

文章的阅读量与统计功能其用的是 Valine 这个库。好像只有这个库可以同时有这两个功能,所以就选了这个。

实现起来也是比较简单的,但是中间遇到了两个问题。

1. vuepress 无法编译成功

window.AV = require('leancloud-storage')
const Valine = require('valine')

new Valine({
    el:'#comment',
    ...
})

如果按照下面的方式初始化评论组件的话,在本地dev模式是可以通过的,但是 npm run build 的时候会提示 window is not undefied 的错误,即使在评论组件加上 VuePress 提供的 ClientOnly 的标识符也会出现这个问题。

最后的解决办法是,以 script 标签的方式引入 leancloud-storage 和 valine 两个库。并在评论组件中轮询检查这两个库是否加载完成,在加载完成之后在初始化评论组件。
代码如下:

<script>
let valine = null
const checkValine = () => {
  if (window.Valine) {
    valine = new Valine({
      appId: '******',
      appKey: '******',
      el: '#comment',
      placeholder: '评论在此',
      avatar: 'monsterid',
      path: window.location.pathname,
      recordIP: true,
      visitor: true
    })
  } else {
    setTimeout(checkValine, 50)
  }
}
export default {
  props: ['show'],
  watch: {
    '$route': 'refresh'
  },
  mounted () {
    checkValine()
  },
  methods: {
    refresh () {
      checkValine()
    }
  }
}
</script>

2.按照教程配置好后,发现文章切换时,评论内容并没有切换

这个主要是由于 Valine 这个库在初始化全局对象时,如果没有传入path这个属性,其内部会缓存当前页面的 path。解决的办法也很简单,只要在传 path 的时候指定的值即可,也即👆上面代码中的 window.location.pathname

一些其他问题

其实在开发过程中还是有一些其他的问题,比如 分类的路由通过首页页面点进去可以直接访问,但是如果直接在浏览器的地址栏输入地址的话 Nginx 会索引不到相应的文件 提示 404 的错误。

这个问题的话,只需要在 nginx 的配置中添加下面👇的配置即可

location / {
  try_files $uri $uri/ /index.html /404.html;
}

其他问题

我建了一个微信群,具体的问题可以加微信群交流

共收到 17 条回复
1Floor Deleted
96

热尔哥

3Floor Deleted
4Floor Deleted
5Floor Deleted
6Floor Deleted
7Floor Deleted
8Floor Deleted
9Floor Deleted
10Floor Deleted
11Floor Deleted
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up