Article

用 Slidev 把 Markdown 變成簡報網站

用 Slidev 把 Markdown 變成簡報網站,從建立專案、自訂樣式到部署上線的完整流程與踩坑紀錄。

本文目錄

最近需要在會議上做簡報,與其用 PowerPoint 或 Google Slides,不如直接做成一個網站,隨時打開瀏覽器就能展示。最後選擇了 Slidev 這個框架,用 Markdown 寫投影片,搭配一些簡單的動效,最終部署成純靜態網站。

這篇文章會分享從技術選型到部署上線的過程,以及一些使用上的心得。

為什麼選 Slidev

一開始有考慮過幾個方案:

方案優點缺點
SlidevMarkdown 撰寫、Vue 組件擴展、內建動效和樣式系統依賴 Vue 生態
reveal.js老牌、外掛多需要寫比較多 HTML,客製化不太方便
自己刻完全自由要自己造翻頁、鍵盤控制、transition 等輪子

Slidev 最吸引我的地方是用 Markdown 就能寫投影片,而且如果需要更複雜的排版,隨時可以在 Markdown 裡面穿插 HTML 和 Vue 組件。內建的 UnoCSS 讓樣式也不用額外設定,寫法跟 Tailwind CSS 幾乎一樣。

建立專案

Bash
UTF-8|2 Lines|
npm init -y
npm install @slidev/cli @slidev/theme-default

package.json 加入 scripts:

JSONpackage.json
UTF-8|6 Lines|
{
  "scripts": {
    "dev": "slidev",
    "build": "slidev build"
  }
}

接著建立 slides.md,這就是你的整份簡報:

Markdownslides.md
UTF-8|15 Lines|
---
theme: default
transition: slide-left
title: My Presentation
---

# Hello

This is the first slide.

---

# Second Slide

This is the second slide.

每一頁用 --- 分隔,最上面的 --- 區塊是全域設定。跑 npm run dev 就能在瀏覽器看到結果了。

投影片結構

因為這是個人簡介,內容不是技術導向,我把它設計成一個比較有節奏感的流程:文字頁和圖片頁交替出現。

封面 → 個人照+簡介 → 主題文字 → 搭配照片 → 主題文字 → 搭配照片 → ... → 結尾

每個主題都拆成獨立的頁面,不會把太多東西塞在同一頁。這樣在操作的時候節奏會比較好,聽眾也比較容易跟上。

自訂樣式

Slidev 預設的樣式比較中性,如果想要有自己的風格,可以在 styles/ 資料夾裡覆寫。建立 styles/index.ts 作為進入點:

TypeScriptstyles/index.ts
UTF-8|1 Line|
import './custom.css'

然後在 custom.css 裡面寫你的樣式:

CSScustom.css
UTF-8|5 Lines|
.slidev-layout {
  background: #f5f0eb !important;
  color: #3a3a3a !important;
  font-family: 'Noto Sans TC', sans-serif !important;
}

這裡的 .slidev-layout 是每一頁投影片的最外層容器,用 !important 覆蓋預設 theme 的樣式。

如果要讓所有頁面都使用同一張背景圖,也可以直接寫在這裡:

CSScustom.css
UTF-8|3 Lines|
.slidev-layout {
  background: url('/images/bg.jpg') center / cover no-repeat !important;
}

圖片放在 public/images/ 下,Slidev 會把 public/ 作為靜態資源的根目錄。

使用 Vue 組件

如果某些排版用純 Markdown 不好實現,可以建立 Vue 組件。把 .vue 檔放在 components/ 資料夾下,Slidev 會自動註冊,直接在 Markdown 裡面用就好:

Vuecomponents/SkillBar.vue
UTF-8|22 Lines|
<script setup lang="ts">
defineProps<{
  name: string
  level: number
}>()
</script>

<template>
  <div class="mb-4">
    <div class="flex justify-between mb-1">
      <span class="text-sm">{{ name }}</span>
      <span class="text-xs">{{ level }}%</span>
    </div>
    <div class="w-full rounded-full h-1.5" style="background: #d4cac0;">
      <div
        class="h-1.5 rounded-full"
        style="background: #8c7b6b;"
        :style="{ width: `${level}%` }"
      />
    </div>
  </div>
</template>

slides.md 裡直接使用:

Markdownslides.md
UTF-8|2 Lines|
<SkillBar name="Vue.js" :level="90" />
<SkillBar name="TypeScript" :level="85" />

動效

頁間切換

在全域 frontmatter 設定預設的 transition:

Markdown
UTF-8|3 Lines|
---
transition: slide-left
---

也可以在個別頁面的 frontmatter 覆寫:

Markdown
UTF-8|3 Lines|
---
transition: fade
---

逐步顯示

<v-click> 包住想要按下一步才出現的內容:

Markdown
UTF-8|7 Lines|
# Title

<v-click>

This text appears after clicking.

</v-click>

這在會議上很實用,可以控制資訊出現的時機,不會一次全部秀出來。

元素進場動畫

如果想要更細緻的動畫效果,可以安裝 @vueuse/motion

Bash
UTF-8|1 Line|
npm install @vueuse/motion

然後在 HTML 標籤上加 v-motion directive:

HTML
UTF-8|5 Lines|
<div v-motion
  :initial="{ opacity: 0, y: 15 }"
  :enter="{ opacity: 1, y: 0, transition: { duration: 1000 } }">
  Content here
</div>

踩到的坑

Markdown 裡的 HTML 縮排會變成 code block

這大概是最容易踩到的問題。在 slides.md 裡面寫 HTML 時,如果縮排超過 4 個空格,Markdown parser 會把它當成程式碼區塊,整段 HTML 就會被原封不動地顯示出來。

解決方法就是把巢狀 HTML 的縮排壓平,不要超過 3 個空格。雖然可讀性會差一點,但至少能正常渲染。

<p> 巢狀問題

如果在 <p> 標籤裡面放了 Markdown 文字,Slidev 會把文字解析成 <p>,導致 <p> 裡面又有 <p>,瀏覽器會報 hydration warning。解決方法是外層改用 <div>

第一頁空白

全域 frontmatter 區塊本身也會被渲染成一頁投影片。如果你的第一頁是封面,可以直接把封面內容跟全域設定放在同一個 frontmatter 區塊裡,加上 layout: none 然後自己排版。

部署

npm run build 會在 dist/ 產出純靜態的 HTML/CSS/JS,可以部署到任何靜態網站託管服務。

我是部署到 Zeabur ,連接 GitHub repo 後設定好 build command(npm run build)和 output directory(dist)就完成了。

如果是部署到 GitHub Pages 之類有 sub-path 的服務,記得在 build 時加上 --base 參數:

Bash
UTF-8|1 Line|
slidev build --base /your-repo-name/

操作快捷鍵

在會議上用筆電操作時,這些快捷鍵很實用:

快捷鍵功能
→ / Space下一頁
上一頁
o總覽模式(快速跳頁)
f全螢幕

這些都是 Slidev 內建的,不需要額外設定。

心得

用 Slidev 做簡報最大的好處是,它就是一個前端專案。想要什麼樣式就寫 CSS,想要什麼互動就寫 Vue 組件,不會被簡報軟體的功能限制住。而且因為是 Markdown,內容的維護和版本控制都很方便。

比較需要注意的是,Slidev 畢竟是把 Markdown 轉成 Vue 組件再渲染,有些 Markdown 和 HTML 混用的邊界情況會比較奇怪(像上面提到的縮排和巢狀問題),需要花一點時間摸索。

整體來說,如果你本身有前端開發的經驗,用 Slidev 做簡報會很順手,也能做出比傳統簡報軟體更有個人風格的東西。