← 全部文章

View Transitions——Astro 的動態頁面導航

從 MPA 的痛點說起

Astro 預設是 MPA(Multi-Page Application)——每次導航都是一次完整的頁面載入。這意味著瀏覽器會重新下載 HTML、CSS、重新執行 JavaScript、重新建立渲染樹。

傳統的 SPA 解決了這個問題,但代價是必須載入框架 runtime。View Transitions 是 Astro 給出的答案:不需要框架,就能實現 SPA 般的流暢頁面切換。

啟用 View Transitions

在 Layout 中引入一個組件即可:

---
import { ViewTransitions } from 'astro:transitions';
---
<!doctype html>
<html lang="zh-TW">
  <head>
    <ViewTransitions />
  </head>
  <body>
    <slot />
  </body>
</html>

這樣一來,網站內的所有導航都會變成無刷新切換,瀏覽器不會重新載入整個頁面,而是僅交換 <body> 內容。

動畫類型

Astro 提供了幾種內置動畫:

<!-- 在 Link 或頁面上使用 -->
<a href="/about" data-astro-transition="slide">關於</a>
<a href="/about" data-astro-transition="fade">關於</a>
<a href="/about" data-astro-transition="morph">關於</a>

各動畫效果

類型 效果
slide 舊頁面左滑,新頁面右滑入
fade 舊頁面淡出,新頁面淡入
morph CSS 動畫 morph,平滑形變

你也可以在頁面 frontmatter 中設定全域過渡:

---
// pages/about.astro
const { transition = { type: 'slide' } } = Astro.props;
---

持久化狀態

View Transitions 的另一個強大功能是狀態持久化。有些元素(如播放器、sidebar 滾動位置)應該在導航中保持狀態:

<div data-astro-transition-persist="player">
  <audio-player />
</div>

被標記為 data-astro-transition-persist 的元素不會被重新渲染,而是直接從舊頁面移動到新頁面。

圖片與媒體預載

為了讓導航更快,Astro 允許你預載連結的頁面資源:

<a href="/long-article" data-astro-preload>詳細文章</a>

當用戶 hover 或觸摸到連結時,Astro 會自動開始下載目標頁面的資源。

與 Islands 的協作

View Transitions 和 Islands 協作得很好:

  • 導航切換頁面時,Islands 組件會重新掛載(除非被 persist)
  • Islands 的 hydration 發生在新頁面掛載後
  • 你可以結合 client:visible 讓島嶼在過渡動畫完成後才載入
<Comments client:visible />

這樣動畫結束後才載入評論區,給用戶即時反饋的同時不阻塞過渡。

自訂動畫

如果你不滿足於內置動畫,可以透過 CSS 完全控制:

/* 自訂進入動畫 */
@keyframes custom-enter {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Astro View Transitions 使用自訂動畫 keyframe 名稱 */
html[data-astro-transition="custom"]::view-transition-new(root) {
  animation: custom-enter 0.4s ease-out;
}

結語

View Transitions 是 Astro 的一個殺手級功能。它讓你不需要學習 SPA 框架,不需要複雜的狀態管理,就能讓網站擁有流暢的頁面切換體驗。

對於部落格和內容網站來說,這意味著你可以兼得 MPA 的簡單性和 SPA 的流暢性——而這正是 Astro 一直在做的事情:讓正確的事情變得簡單