什麼是 VitePress ?
VitePress 是一個靜態站點生成器 (SSG),專為構建快速、以內容為中心的站點而設計。簡而言之,VitePress 獲取用 Markdown 編寫的內容,對其應用主題,並生成可以輕鬆部署到任何地方的靜態 HTML 頁面。
參考官網
⚠️因為官方網站的原因,此文所有的鏈接地址可能會進入 404 頁面,此時需要我們從官網的根目錄地址進入https://vitejs.cn/vitepress/
VitePress 的配置 ⚙️
配置需要達到的目標
- 靜態頁面只包含內容區域和文檔側邊欄
- 靜態頁面路由可以在Web中正常訪問 🔥
- 根據需求進行基本配置
基本準備
- Node.js 18 及以上版本
- 初始準備參考
-
項目根目錄安裝 vitepress
不同的管理工具,有不同的安裝命令,你只需要選擇其中一個即可。
npm add -D vitepresspnpm add -D vitepressyarn add -D vitepressbun add -D vitepress
-
vitepress 初始化及安裝嚮導
不同的管理工具,有不同的安裝命令,你只需要選擇其中一個即可。
npx vitepress initpnpm vitepress inityarn vitepress initbun vitepress init┌ Welcome to VitePress! │ ◇ Where should VitePress initialize the config? │ ./docs // [!code focus] [!code warning] │ ◇ Site title: │ My Awesome Project │ ◇ Site description: │ A VitePress Site │ ◆ Theme: │ ● Default Theme (Out of the box, good-looking docs) │ ○ Default Theme + Customization │ ○ Custom Theme └在安裝嚮導過程中需要選擇
./docs或./自定義目錄中搭建 VitePress 項目,以便與 Web 項目源碼區分開來。
文件配置
我們要知道 config 文件中包含了所需的大部分配置,.md 文件頂部包含部分配置和需要覆蓋 config 文件的配置,也就是説 .md 文件顯示可以做定製化配置。配置參考
-
config.mts或config.ts或config.js:尤其要關注代碼高亮部分的註釋🔥import { defineConfig } from 'vitepress' // https://vitepress.dev/reference/site-config export default defineConfig({ title: "My Awesome Project", description: "A VitePress Site", lang: 'zh-CN', // 站點的 lang 屬性 base: '/markdown/', // 🔥基於主路徑的站點訪問路徑 outDir: '../public/markdown', // 🔥項目的構建輸出位置,相對於 Vitepress 項目的根目錄 lastUpdated: true, // 🔥啓用 Git 獲取每個頁面的最後更新時間戳 markdown: { // 🔥markdown 擴展 lineNumbers: true, // 代碼塊啓用行號 math: true, // 支持數學方程,需要下載 markdown-it-mathjax3 插件 image: { // 默認禁用圖片懶加載 lazyLoading: true }, // config: (md) =>{ // // 使用更多的 Markdown-it 插件! // // md.use(?) // } }, themeConfig: { outline: { // 🔥文檔側邊欄配置 level: [2, 6], label: '頁面導航' }, // https://vitepress.dev/reference/default-theme-config nav: [ // 可忽略配置 { text: 'Home', link: '/' }, { text: 'Examples', link: '/markdown-examples' } ], sidebar: [ // 🔥如果需要上下翻頁,則必須把所有的文件配置在裏面,但不拘泥於層級結構 { text: 'Examples', items: [ { text: 'Markdown Examples', link: '/markdown-examples' }, { text: 'Runtime API Examples', link: '/api-examples' } ] } ], socialLinks: [ { icon: 'github', link: 'https://github.com/vuejs/vitepress' } ], docFooter: { // 🔥用於自定義出現在上一頁和下一頁鏈接上方的文本 prev: '上一篇', next: '下一篇' } } }) -
xxx.md:navbar: false隱藏導航欄,sidebar: false隱藏項目側邊欄--- navbar: false sidebar: false --- -
package.json:- 在執行初始化
npx vitepress init命令後,腳本中會自動添加三條docs命令。 - 如果 Web 與 Vitepress 相應程序已配置好,只需要驅動數據就可以更新視圖,則項目打包時可以定義一個複合指令
mdbuild;如果md內容發生變化時需要先yarn docs:build,則不需要複合指令。 - 相應的指令可根據項目靈活配置,目前配置已滿足此實踐的需求。
{ "scripts": { "docs:dev": "vitepress dev docs", "docs:build": "vitepress build docs", "docs:preview": "vitepress preview docs", "mdbuild": "yarn docs:build && yarn build" } } - 在執行初始化
Web 頁面組件配置 ⚙️
配置需要達到的目標
- 定義一個展示 Markdown 內容的容器組件
- 防止 Vitepress 頁面不存在時,iframe 嵌套死循環
- 響應 Web 頁面主題切換
組件不拘泥於 Vue、React 亦或者原生 html 寫法,以下是以 Vue 組件為例。
假設定義一個 MarkdownViewer.vue 組件:
checkUrlExists方法:判斷頁面地址是否可訪問,以此來防止 iframe 嵌套死循環。changeTheme方法:通過增刪dark類名來實現 Vitepress 頁面的主題切換。- 🚀 如果還有展示
word、pdf等靜態文件可把iframe替換或結合object標籤使用。
<template>
<div>
<button @click="changeTheme">切換主題</button>
<div v-if="checking" class="loading">檢查頁面是否存在...</div>
<div v-else-if="pageExists">
<iframe
:src="url"
@load="onLoad"
@error="onError"
width="100%"
height="800"
frameborder="0"
ref="iframe"
></iframe>
</div>
<div v-else class="not-found">
<h3>頁面不存在</h3>
<p>請求的頁面 <code>{{ url }}</code> 不存在</p>
<button @click="$emit('close')">關閉</button>
</div>
</div>
</template>
<script>
export default {
name: 'PreCheckedIframe',
props: {
url: {
type: String,
required: true
}
},
data() {
return {
checking: true,
pageExists: false,
loadError: false,
initClassName: '',
}
},
async mounted() {
await this.checkUrlExists();
},
methods: {
changeTheme() {
const iframeHtml = this.$refs.iframe?.contentDocument?.querySelector('html')
if (!iframeHtml) return
if (!this.initClassName) this.initClassName = iframeHtml.className
if (iframeHtml.className?.includes('dark')) {
iframeHtml.className = this.initClassName
} else {
iframeHtml.className += ' dark'
}
console.log(iframeHtml.className)
},
async checkUrlExists() {
try {
const response = await fetch(this.url, {
method: 'HEAD',
mode: 'no-cors', // 如果是跨域請求
cache: 'no-cache'
});
this.pageExists = response.ok;
} catch (error) {
console.error('檢查 URL 失敗:', error);
this.pageExists = false;
} finally {
this.checking = false;
}
},
onLoad() {
console.log('iframe 加載成功');
this.loadError = false;
},
onError() {
console.error('iframe 加載失敗');
this.loadError = true;
this.pageExists = false;
}
},
watch: {
async url() {
this.checking = true;
await this.checkUrlExists();
}
}
}
</script>
到此為止,項目所需的功能已經實現。👇Vitepress 中 Markdown 語法的擴展可可直接參考官網。