VuePress 部落格優化之增加 Vssue 評論功能

冴羽發表於2022-03-10

前言

《一篇帶你用 VuePress + Github Pages 搭建部落格》中,我們使用 VuePress 搭建了一個部落格,最終的效果檢視:TypeScript 中文文件

本篇講講如何使用 Vssue 快速的實現評論功能。

主題內建

因為我用的是 vuepress-theme-reco 主題,主題內建評論外掛 @vuepress-reco/vuepress-plugin-comments,可以根據自己的喜好選擇 Valine 或者 Vssue。

那我們來介紹下 Vssue。

Vssue

官網:https://vssue.js.org/zh/

Vssue 是一個 Vue 驅動的、基於 Issue 的評論外掛。

特點是支援多個程式碼託管平臺,包括 GitHub、GitLab、Bitbucket、 Gitee 和 Gitea。因為基於 Vue,可以作為 Vue 外掛使用,輕鬆整合到 Vue 應用中。

你可以點選官網連結,進入首頁,直接在頁面的評論框中體驗評論效果。

開始

1. 建立 GitHub OAuth App

這裡我們使用 GitHub 作為託管平臺,開啟 GitHub 的開發者設定:https://github.com/settings/developers

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

為了方便本地測試,Homepage URLAuthorization callback URL 我們都寫成 http://localhost:8080,建立應用後,我們再點選 Generate a new client secret 生成 Client secrets

最後就會獲取 Client IDClient 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. 效果展示

執行專案,就可以看到效果:

但是注意,在一開始沒有評論的時候,需要點選圖中的 「點選建立 Issue」,才能正常的進行評論,當你點選「點選建立 Issue」的時候,你對應的 Github 倉庫也會建立一條 issue,接下來的回覆都會出現在這條 issue 中。

這是有評論後的效果:

4. 評論部分開啟

如果你想預設不載入評論,而只在某些頁面顯示評論功能,可以在 valineConfigvssueConfig 中設定 showComment: false,並在需要展示評論的頁面 設定 isShowComments: true

如果僅是某篇文章不想設定開啟評論功能,可以在 front-matter 設定 isShowComments: false

問題 :多個頁面的評論混合在一起

如果你多在幾個頁面建立評論,你會發現,所有的評論都是在一起的,這是因為 Vssue 在嘗試載入評論時,是根據 labels 和 title 來請求對應的 Issue。

參照 Vssue 的配置文件:https://vssue.js.org/zh/options/,其實我們是可以配置 labels 等屬性的,但因為我們沒有配置,所以請求的時候請求的都是同一條,自然就混合在了一起。

如果我們只是做一個留言板,那倒沒有什麼問題,但比如我的是 TypeScript 文件,每篇文章的評論我肯定希望是分開的,那該怎麼實現呢?

雖然我們可以直接在 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'
    }
  }  
}

但如果不能動態的設定 lables ,其實還是沒有什麼用。

最終我決定,不使用 reco 主題內建的這個評論外掛,而是改為使用 Vssue 提供的外掛,其實 reco 內建的這個評論外掛是基於 Vssue 提供的外掛進行的一層封裝。

那怎麼實現呢?參照 Vssue 提供的 VuePress 指南

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 已經註冊為 Vue 元件,你可以在你的 VuePress Markdown 檔案中直接使用它。

 <template>
  <Vssue :issue-id="228" />
</template>

參照 Vssue 提供的配置文件

Vssue 元件支援傳入三個屬性:

  1. title

labels 和 title 是儲存評論的對應 Issue 的識別符號。

所以請確保不同頁面的 Vssue 使用不同的 title。擁有相同 title 的 Vssue 會對應到同一個 Issue,也就會有同樣的評論。

  1. issueId

如果設定了 issueId,Vssue 將會直接使用它來確定要使用哪個 Issue,而不是根據 labels 和 title 來查詢對應的 Issue。這會加快 Vssue 的初始化過程。

但是在這種情況下,你必須要 手動建立 Issue。如果對應的 Issue 不存在,Vssue 不會嘗試為你建立一個新的 Issue。

  1. options

在 prop options 中設定的屬性,會覆蓋通過 Vue.use() 設定的屬性。它可以接收 VssueOptions 中的所有配置。

你可以把通過 Vue.use() 設定的配置當作 Vssue 的 全域性 / 預設 配置,把通過 prop options 設定的配置當作 區域性 配置。

因為我翻譯的 TypeScript 文件也同時同步在我的 GitHub 上,所以我希望評論也是同步的,為此我選擇使用 issueId 來獲取指定 issue 的評論資料,普通使用的話,還是使用自定義的 title 屬性。

4. 效果展示

我們來看看效果:

問題:評論區位置調整

上圖之所以用紅色矩形進行了標註,是想讓大家注意到,因為我們的 Vssue 元件程式碼是寫在 md 檔案裡的,所以評論和內容是連在一起的,而更新時間和上下文連結則是在底部的,如果評論內容比較長的話,會略顯奇怪。

那如果我們像讓評論區域出現在最底部呢?該怎麼實現呢?

為此我嘗試了很多方法,比如在掛載的時候將 DOM 元素移動到底部,在 enhanceApp.js 中掛載元件,但最終都以失敗告終。

最後,我決定,不講武德了,直接改 reco 內建的 vuepress-plugin-comments 元件原始碼:

1. 修改 vuepress-plugin-comments 原始碼

node_modules 中找到 vuepress-plugin-comments 的程式碼目錄,修改 /.bin/Vssue.vue檔案:

// 元件加了一行 :issue-id="issueId"
<template>
  <VssueComponent
    class="vssue-wrapper"
    :issue-id="issueId"
    :key="key"
    :options="vssueOptions"
  />
</template>

// script 中加入 issueId 計算屬性
<script>
export default {
  // ...
  computed: {
    vssueOptions () {
      // ...
    },
    issueId () {
      return this.$page.frontmatter.issueId || null
    }
  },
    // ...
}
</script>

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. 效果展示

系列文章

部落格搭建系列是我至今寫的唯一一個偏實戰的系列教程,預計 20 篇左右,講解如何使用 VuePress 搭建、優化部落格,並部署到 GitHub、Gitee、私有伺服器等平臺。本篇為第 26 篇,全系列文章地址:https://github.com/mqyqingfeng/Blog

微信:「mqyqingfeng」,加我進冴羽唯一的讀者群。

如果有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。如果喜歡或者有所啟發,歡迎 star,對作者也是一種鼓勵。

相關文章