VuePress 集成第三方评论模块
VuePress 是一个 Vue 驱动的静态网站生成器,用来写文档的体验很好,本站就是基于 VuePress 的。VuePress 官方正在开发针对博客的优化功能 Blog Support roadmap ,已经有人在喊建议集成 disqus(ps:disqus 已经被墙)了,有兴趣的同学可以去投个票。
在官方之前,大家也可以参考本文为自己的博客/文档添加评论模块。
本文采用 Gitalk 作为示例,效果看文章底部。如果想集成其它第三方模块,本文代码也有一定参考性。
注意:Gitalk 要求用户登录 github 才能评论
注册 OAuth application
参考 gitalk ,本博客下的评论区即是 gitalk,你会得到一个 client ID 和一个 client secret,这个将被用于之后的用户登录。
创建或准备一个 github 仓库存储评论
Gitalk 将评论都存储在仓库 issue 中,同时要求用户登录 github 才能评论,所以需要先准备一个仓库。 本博客托管在 Github Pages 上,所以直接使用 hughfenghen.github.io 仓库 来存储评论了。
创建一个 enhanceApp.js
文件
在 ./vuepress
目录下创建 enhanceApp.js
文件, copy 以下代码到文件中,填写代码中的 xxx
部分。 如果已存在 enhanceApp
文件,则 copy try...catch
代码块和 integrateGitalk
函数
// 重试
function tryRun (fn, times = 3) {
let execCount = 1
fn(next)
function next(delay) {
if (execCount >= times) return
setTimeout(() => {
execCount += 1
fn(next)
}, delay);
}
}
function integrateGitalk(router) {
const linkGitalk = document.createElement('link')
linkGitalk.href = 'https://unpkg.com/gitalk @1/dist/gitalk.css'
linkGitalk.rel = 'stylesheet'
const scriptGitalk = document.createElement('script')
scriptGitalk.src = 'https://unpkg.com/gitalk @1/dist/gitalk.min.js'
document.body.appendChild(linkGitalk)
document.body.appendChild(scriptGitalk)
router.afterEach((to, from) => {
// 页面滚动,hash 值变化,也会触发 afterEach 钩子,避免重新渲染
if (to.path === from.path) return
// 已被初始化则根据页面重新渲染 评论区
tryRun((next) => {
const $page = document.querySelector('.page')
if ($page && window.Gitalk) {
// 如果不 setTimeout 取到是上一篇文档的标题
setTimeout(() => {
renderGitalk($page, to.path)
}, 1);
} else {
next(500)
}
}, 10)
})
function renderGitalk(parentEl, path) {
// 移除旧节点,避免页面切换 评论区内容串掉
const oldEl = document.getElementById('comments-container');
oldEl && oldEl.parentNode.removeChild(oldEl);
const commentsContainer = document.createElement('div')
commentsContainer.id = 'comments-container'
commentsContainer.classList.add('content')
commentsContainer.style = 'padding: 0 30px;'
parentEl.appendChild(commentsContainer)
const gitalk = new Gitalk({
clientID: 'xxx', // 第一步注册 OAuth application 后获取到的 Client ID
clientSecret: 'xxx', // 第一步注册 OAuth application 后获取到的 Clien Secret
repo: 'hughfenghen.github.io',
owner: 'hughfenghen',
admin: ['hughfenghen'],
id: location.pathname, // Ensure uniqueness and length less than 50
distractionFreeMode: false // Facebook-like distraction free mode
})
gitalk.render('comments-container')
}
}
export default ({
Vue, // VuePress 正在使用的 Vue 构造函数
options, // 附加到根实例的一些选项
router, // 当前应用的路由实例
siteData // 站点元数据
}) => {
try {
// 生成静态页时在 node 中执行,没有 document 对象
document && integrateGitalk(router)
} catch (e) {
console.error(e.message)
}
}
VuePress deploy
部署项目,如果还未部署,请参考 部署文档
注意事项
- VuePress 构建的时候,在 node 中执行代码生成各个页面的时候,此时 document 为 undefined,所以写在 try...catch 块中,构建时必然会执行到 catch 块代码。目前没找到环境检测方法。
document.querySelector('.page')
,page、content 是 VuePress 现在默认的 class,后续升级可能会报错,届时需要同步改一下。- 如果需要对本文提供的代码进行改造,
renderGitalk
在每次路由切换后都必须执行,Gitalk 的 ID 是页面的 fullPath,如果未执行会导致页面间评论混乱。 - 评论之后刷新页面,如果发现评论不见了,是因为页面缓存,不用担心,可以点击 Issue Page(Like 右侧)检查。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 基于 Vue directive 实现声明式埋点方案
下一篇: 谈谈自己对于 AOP 的了解
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论