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 一直在做的事情:讓正確的事情變得簡單。