🏝️ Islands 架构
Astro 开创的前端架构模式,选择性水合交互组件:
🎯 核心思想
- 页面默认渲染为静态 HTML
- 只有交互组件加载 JavaScript
- 每个岛屿独立水合,不阻塞其他
- 并行加载,优先级可控
Client 指令
| 指令 | 说明 |
|---|---|
| client:load | 页面加载时立即水合 |
| client:idle | 浏览器空闲时水合 |
| client:visible | 进入视口时水合 |
| client:media | 匹配媒体查询时水合 |
| client:only | 跳过服务端渲染 |
📦 零 JS 默认
Astro 默认不发送任何 JavaScript 到客户端:
astro
---
// 这个组件不会发送任何 JS 到客户端
const items = ['苹果', '香蕉', '橙子'];
---
<ul>
{items.map(item => <li>{item}</li>)}
</ul>
对比传统框架
| 框架 | 默认 JS | 水合方式 |
|---|---|---|
| Astro | 0 KB | 选择性 |
| Next.js | ~80 KB | 全页水合 |
| Gatsby | ~120 KB | 全页水合 |
🎨 多框架支持
在同一个项目中混用不同框架:
astro
---
import ReactWidget from './ReactWidget.jsx';
import VueWidget from './VueWidget.vue';
import SvelteWidget from './SvelteWidget.svelte';
---
<!-- React 组件 -->
<ReactWidget client:visible />
<!-- Vue 组件 -->
<VueWidget client:idle />
<!-- Svelte 组件 -->
<SvelteWidget client:load />
📚 Content Collections
类型安全的内容管理:
typescript (src/content/config.ts)
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
schema: z.object({
title: z.string(),
date: z.date(),
tags: z.array(z.string()),
}),
});
export const collections = { blog };
astro
---
import { getCollection } from 'astro:content';
const posts = await getCollection('blog');
---
{posts.map(post => (
<article>
<h2>{post.data.title}</h2>
<p>{post.data.date}</p>
</article>
))}
🔄 View Transitions
页面切换动画,无需额外配置:
astro
---
import { ViewTransitions } from 'astro:assets/transitions';
---
<html>
<head>
<ViewTransitions />
</head>
<body>
<!-- 页面切换时自动平滑过渡 -->
</body>
</html>