VuePress 博客優(yōu)化之增加 Vssue 評論功能
在 《一篇帶你用 VuePress + Github Pages 搭建博客》[1]中,我們使用 VuePress 搭建了一個博客,最終的效果查看:TypeScript 中文文檔[2]。
本篇講講如何使用 Vssue 快速的實現(xiàn)評論功能。
主題內(nèi)置
因為我用的是 vuepress-theme-reco 主題,主題內(nèi)置評論插件 @vuepress-reco/vuepress-plugin-comments,可以根據(jù)自己的喜好選擇 Valine 或者 Vssue。
那我們來介紹下 Vssue。
Vssue
官網(wǎng):https://vssue.js.org/zh/[3]
Vssue 是一個 Vue 驅(qū)動的、基于 Issue 的評論插件。
特點是支持多個代碼托管平臺,包括 GitHub、GitLab、Bitbucket、 Gitee 和 Gitea。因為基于 Vue,可以作為 Vue 插件使用,輕松集成到 Vue 應用中。
你可以點擊官網(wǎng)鏈接,進入首頁,直接在頁面的評論框中體驗評論效果。
開始
1. 創(chuàng)建 GitHub OAuth App
這里我們使用 GitHub 作為托管平臺,打開 GitHub 的開發(fā)者設置:https://github.com/settings/developers[4]

選擇「Oauth Apps」,然后點擊「Register a new application」:

為了方便本地測試,Homepage URL 和 Authorization callback URL 我們都寫成 http://localhost:8080,創(chuàng)建應用后,我們再點擊 Generate a new client secret 生成 Client secrets:

最后就會獲取 Client ID 和 Client secrets。
2. 修改 config.js
module.exports?=?{
??theme:?'reco',
??themeConfig:?{
????vssueConfig:?{
??????platform:?'github',
??????owner:?'OWNER_OF_REPO',
??????repo:?'NAME_OF_REPO',
??????clientId:?'YOUR_CLIENT_ID',
??????clientSecret:?'YOUR_CLIENT_SECRET',
????}
??}??
}
3. 效果展示
運行項目,就可以看到效果:

但是注意,在一開始沒有評論的時候,需要點擊圖中的 「點擊創(chuàng)建 Issue」,才能正常的進行評論,當你點擊「點擊創(chuàng)建 Issue」的時候,你對應的 Github 倉庫也會建立一條 issue,接下來的回復都會出現(xiàn)在這條 issue 中。
這是有評論后的效果:

4. 評論部分開啟
如果你想默認不加載評論,而只在某些頁面顯示評論功能,可以在 valineConfig 或 vssueConfig 中設置 showComment: false,并在需要展示評論的頁面 設置 isShowComments: true。
如果僅是某篇文章不想設置開啟評論功能,可以在 front-matter 設置 isShowComments: false。
問題 :多個頁面的評論混合在一起
如果你多在幾個頁面創(chuàng)建評論,你會發(fā)現(xiàn),所有的評論都是在一起的,這是因為 Vssue 在嘗試加載評論時,是根據(jù) labels 和 title 來請求對應的 Issue。
參照 Vssue 的配置文檔:https://vssue.js.org/zh/options/[5],其實我們是可以配置 labels 等屬性的,但因為我們沒有配置,所以請求的時候請求的都是同一條,自然就混合在了一起。
如果我們只是做一個留言板,那倒沒有什么問題,但比如我的是 TypeScript 文檔,每篇文章的評論我肯定希望是分開的,那該怎么實現(xiàn)呢?
雖然我們可以直接在 config.js里這樣寫:
module.exports?=?{
??theme:?'reco',
??themeConfig:?{
????vssueConfig:?{
??????platform:?'github',
??????owner:?'OWNER_OF_REPO',
??????repo:?'NAME_OF_REPO',
??????clientId:?'YOUR_CLIENT_ID',
??????clientSecret:?'YOUR_CLIENT_SECRET',
??????labels:?'xxx'
????}
??}??
}
但如果不能動態(tài)的設置 lables ,其實還是沒有什么用。
最終我決定,不使用 reco 主題內(nèi)置的這個評論插件,而是改為使用 Vssue 提供的插件,其實 reco 內(nèi)置的這個評論插件是基于 Vssue 提供的插件進行的一層封裝。
那怎么實現(xiàn)呢?參照 Vssue 提供的 VuePress 指南[6]:
1. 安裝插件
yarn?add?@vssue/vuepress-plugin-vssue?-D
yarn?add?@vssue/api-github-v3?-D
2. 使用插件
//?.vuepress/config.js
module.exports?=?{
??plugins:?{
????'@vssue/vuepress-plugin-vssue':?{
??????platform:?'github',
??????owner:?'OWNER_OF_REPO',
??????repo:?'NAME_OF_REPO',
??????clientId:?'YOUR_CLIENT_ID',
??????clientSecret:?'YOUR_CLIENT_SECRET',
????},
??},
};
3. 使用 Vssue 組件
Vssue 已經(jīng)注冊為 Vue 組件,你可以在你的 VuePress Markdown 文件中直接使用它。
?
??<Vssue?:issue-id="228"?/>
</template>
參照 Vssue 提供的配置文檔[7]:
Vssue 組件支持傳入三個屬性:
title
labels 和 title 是存儲評論的對應 Issue 的標識符。
所以請確保不同頁面的 Vssue 使用不同的 title。擁有相同 title 的 Vssue 會對應到同一個 Issue,也就會有同樣的評論。
issueId
如果設置了 issueId,Vssue 將會直接使用它來確定要使用哪個 Issue,而不是根據(jù) labels 和 title 來查找對應的 Issue。這會加快 Vssue 的初始化過程。
但是在這種情況下,你必須要 手動創(chuàng)建 Issue。如果對應的 Issue 不存在,Vssue 不會嘗試為你創(chuàng)建一個新的 Issue。
options
在 prop options 中設置的屬性,會覆蓋通過 Vue.use() 設置的屬性。它可以接收 VssueOptions 中的所有配置。
你可以把通過 Vue.use() 設置的配置當作 Vssue 的 全局 / 默認 配置,把通過 prop options 設置的配置當作 局部 配置。
因為我翻譯的 TypeScript 文檔也同時同步在我的 GitHub[8] 上,所以我希望評論也是同步的,為此我選擇使用 issueId 來獲取指定 issue 的評論數(shù)據(jù),普通使用的話,還是使用自定義的 title 屬性。
4. 效果展示
我們來看看效果:

問題:評論區(qū)位置調(diào)整
上圖之所以用紅色矩形進行了標注,是想讓大家注意到,因為我們的 Vssue 組件代碼是寫在 md 文件里的,所以評論和內(nèi)容是連在一起的,而更新時間和上下文鏈接則是在底部的,如果評論內(nèi)容比較長的話,會略顯奇怪。
那如果我們像讓評論區(qū)域出現(xiàn)在最底部呢?該怎么實現(xiàn)呢?
為此我嘗試了很多方法,比如在掛載的時候?qū)?DOM 元素移動到底部,在 enhanceApp.js 中掛載組件,但最終都以失敗告終。
最后,我決定,不講武德了,直接改 reco 內(nèi)置的 vuepress-plugin-comments 組件源碼:
1. 修改 vuepress-plugin-comments 源碼
在 node_modules 中找到 vuepress-plugin-comments 的代碼目錄,修改 /.bin/Vssue.vue文件:
// 組件加了一行 :issue-id="issueId"
class="vssue-wrapper"
:issue-id="issueId"
:key="key"
:options="vssueOptions"
/>
// script 中加入 issueId 計算屬性
2. 修改 config.js
module.exports?=?{
??theme:?'reco',
??themeConfig:?{
??vssueConfig:?{
??????platform:?'github',
??????owner:?'mqyqingfeng',
??????repo:?'Blog',
??????clientId:?'YOUR_CLIENT_ID',
??????clientSecret:?'YOUR_CLIENT_SECRET'
???},
??}??
}
3. md 文件加入 issueId 屬性
在每個 markdown 文件的最開頭添加 Front Matter,寫入文章對應的 issueId:
---
issueId:?228
---
4. 效果展示

