实验性特性
Nuxt 通过 experimental 配置项提供实验性功能。这些特性已经可用,但 API 可能会在未来版本中调整。
export default defineNuxtConfig({
experimental: {
// ...
},
})"实验性"意味着什么?
实验性特性功能完整,但不保证向后兼容。适合愿意提前体验新功能的开发者。建议在充分测试后再用于生产环境。
payloadExtraction
为什么关注 Payload 提取?
传统的 SSR 是将数据内联到 HTML 中,浏览器解析 HTML 后直接使用数据,不重复请求。Payload 提取额外生成 _payload.json 文件,浏览器缓存后可以避免重复渲染,大幅提升后续访问速度。
experimental: {
payloadExtraction: true, // 启用 Payload 提取
payloadExtraction: 'client', // v4.4+:内联 + 文件(推荐)
}| 模式 | 行为 | 适用场景 |
|---|---|---|
true | 只生成 _payload.json 文件 | 静态站点 |
'client' | HTML 内联 + 生成文件 + LRU 缓存 | 推荐,兼顾首屏和缓存 |
viewTransition
为什么用它?
原生 View Transitions API 让页面切换有流畅的过渡动画(淡入淡出、共享元素动画等),比 CSS transition 更自然,且由浏览器优化性能。
experimental: {
viewTransition: true,
}启用后页面切换时自动使用浏览器原生过渡动画,可以通过 CSS 自定义:
/* 自定义过渡效果 */
::view-transition-old(root) {
animation: 0.3s ease-out both fade-out;
}
::view-transition-new(root) {
animation: 0.3s ease-in both fade-in;
}
@keyframes fade-out { to { opacity: 0; } }
@keyframes fade-in { from { opacity: 0; } }INFO
️ 浏览器兼容性: 目前 Chrome/Edge 支持 Firefox 和 Safari 部分支持。不支持的浏览器会自动回退为无动画,不会报错
typedPages
为什么用它?
默认情况下 navigateTo('/users') 的路径是字符串,拼错了不会报错。启用后 useRouter().push() 和 <NuxtLink :to> 会获得类型提示,路径拼写错误会在编译时报错。
experimental: {
typedPages: true,
}效果对比:
// ❌ 默认:路径拼写错误不会报错
navigateTo('/user') // 实际路径是 /users,但不会报错
// ✅ typedPages 启用后:类型检查会报错
navigateTo('/user') // TypeScript 报错:路径不存在TIP
强烈推荐启用 特别是在大型项目中,能有效避免路由拼写错误
normalizeComponentNames
规范化组件名称,使页面组件名称与路由名称一致:
experimental: {
normalizeComponentNames: true,
}启用后 DevTools 中显示的组件名更易识别,方便调试。
writeEarlyHints
为什么用它?
SSR 时服务端需要先渲染页面才能知道需要哪些资源(CSS、JS),渲染完成前浏览器只能等待。Early Hints(HTTP 103)让服务端在渲染完成前就告诉浏览器即将需要的资源,浏览器可以提前下载。
experimental: {
writeEarlyHints: true,
}适合使用 CDN 且首屏性能要求高的场景。
clientFallback
启用 <NuxtClientFallback> 组件:
experimental: {
clientFallback: true,
}<template>
<!-- SSR 渲染成功但客户端 Hydration 失败时,显示 fallback -->
<NuxtClientFallback>
<HeavyComponent />
<template #fallback>
<p>加载失败,请刷新页面</p>
</template>
</NuxtClientFallback>
</template>TIP
与 <ClientOnly> 的区别:ClientOnly 完全跳过 SSR 而 NuxtClientFallback 先尝试 SSR,只有客户端 Hydration 失败时才降级
componentIslands
为什么叫 "Islands"(岛屿)?
这是 Islands 架构的概念——大部分页面是静态的 HTML(海洋),只有少数交互组件(岛屿)需要在客户端 Hydration。减少了客户端 JavaScript 体积。
experimental: {
componentIslands: true,
}支持 .server.vue 服务端组件:
<!-- components/Stats.server.vue -->
<!-- 只在服务端渲染,不发送 JS 到客户端 -->
<script setup>
// 可以直接查询数据库
const stats = await $fetch('/api/stats')
</script>
<template>
<div>{{ stats.total }} 次访问</div>
</template>INFO
️ 服务端组件的限制: 不能有交互(v-on、v-model)、不能使用 onMounted、不能使用客户端 API(window、document) 适合纯展示组件(图表、统计数据等)
inlineRouteRules
在页面中定义的路由规则会被内联到路由配置中:
experimental: {
inlineRouteRules: true,
}让 defineRouteRules 定义的规则直接生效,而不需要重启开发服务器。
appManifest
自动生成应用清单,支持路由规则预取:
experimental: {
appManifest: true,
}启用后浏览器可以提前知道每个路由的渲染模式(SSR/SPA/预渲染),避免不必要的请求。
defaults
为常用组合式函数设置默认选项,避免每次调用都重复配置:
experimental: {
defaults: {
useAsyncData: {
deep: false, // 默认不深度监听(性能优化)
},
useFetch: {
dedupe: 'defer', // 默认去重策略
},
},
}TIP
这在团队协作中特别有用——统一默认行为 避免不同开发者配置不一致
特性速查
| 特性 | 稳定性 | 推荐场景 | 浏览器要求 |
|---|---|---|---|
payloadExtraction: 'client' | ⭐ 稳定 | 所有项目 | 无 |
typedPages | ⭐ 稳定 | 所有项目 | 无 |
viewTransition | ⚡ 较新 | 注重页面动画的项目 | Chrome/Edge |
componentIslands | ⚡ 较新 | 纯展示组件多、性能敏感 | 无 |
defaults | ⭐ 稳定 | 团队协作项目 | 无 |
clientFallback | ⚡ 较新 | 组件 Hydration 不稳定时 | 无 |
writeEarlyHints | ⚡ 较新 | CDN 部署 + 首屏性能敏感 | 需 CDN 支持 |
normalizeComponentNames | ⭐ 稳定 | 调试需求 | 无 |
inlineRouteRules | ⚡ 较新 | 频繁调整路由规则 | 无 |
appManifest | ⚡ 较新 | 路由预取优化 | 无 |
注意事项
- 实验性功能可能变化——API 可能在未来版本中调整,升级时注意查看 changelog
- 默认值可能改变——当前默认关闭的特性未来可能默认开启
- 生产环境使用前充分测试——特别是标记为"较新"的特性
- 反馈问题——在 GitHub 上报告问题帮助 Nuxt 改进