在 Markdown 使用 Vue
每一個 Markdown 檔最後都會編成 Vue 單檔元件。因此你可以在文件中間寫 {{ }}、v-bind,或插入自己的元件——這是 VitePress 相對許多 SSG 最大的差別。
官方說明:〈在 Markdown 中使用 Vue〉。
靜態內容仍是靜態的
Vue 編譯器會把不會變的 HTML 標成靜態。第一次載入時,這些區塊不必走完整 hydration,JS 體積也比較小。只有真正用到 Vue 語法的部分才會變成互動島嶼。
所以不要為了「用一下 Vue」把整頁改成元件;說明文字維持 Markdown,只有示範區才放元件。
單頁匯入元件
只有少數頁面用到時,在該 .md 直接匯入,打包時才會把元件拆到該頁:
<script setup>
import DemoCounter from '../components/DemoCounter.vue'
</script>
試著點下面的按鈕:
<DemoCounter />
元件名稱請用 PascalCase 或帶連字號(demo-counter)。全小寫單字會被當成原生 HTML,容易造成 hydration 對不上。
全站註冊
側欄、提示框這類幾乎每頁都出現的元件,在 .vitepress/theme/index.js 的 enhanceApp 註冊一次即可。做法見官方〈擴展預設主題〉。
SSR 相容
build 會在 Node 裡執行元件以產出 HTML。因此:
- 不要在頂層直接碰
window、document、localStorage。 - 瀏覽器專用邏輯放到
onMounted,或先判斷typeof window !== 'undefined'。 - 若建置報 hydration mismatch,通常是伺服器 HTML 與瀏覽器第一次渲染結果不一致,例如用了當下時間、隨機數,或把區塊元素塞進會被包成
<p>的地方。
需要在文件裡示範元件庫時,常見做法是:在 theme 的 enhanceApp 裡 app.use(YourUI),Markdown 中間就可以寫 <YourButton>範例</YourButton>。