---
title: "Nuxt 4.4"
description: "Nuxt 4.4 带来了自定义 useFetch/useAsyncData 工厂、vue-router v5、新的无障碍播报器、类型化布局 props、构建性能分析、更智能的 payload 处理，以及更多功能。"
canonical_url: "https://nuxt.zhcndoc.com/blog/v4-4"
---
# Nuxt 4.4

> Nuxt 4.4 带来了自定义 useFetch/useAsyncData 工厂、vue-router v5、新的无障碍播报器、类型化布局 props、构建性能分析、更智能的 payload 处理，以及更多功能。

## 🏭 `createUseFetch` 和 `createUseAsyncData`

现在你可以使用自己的默认选项创建 **自定义实例** 的 `useFetch` 和 `useAsyncData` 了（[#32300](https://github.com/nuxt/nuxt/pull/32300)）。

```ts [composables/api.ts]
// 简单默认值
export const useClientFetch = createUseFetch({
  server: false,
})

// 带完整合并控制的动态默认值
export const useApiFetch = createUseFetch((currentOptions) => {
  const runtimeConfig = useRuntimeConfig()

  return {
    ...currentOptions,
    baseURL: currentOptions.baseURL ?? runtimeConfig.public.baseApiUrl,
  }
})
```

然后像使用 `useFetch` 一样使用它们 – 它们具有完整类型支持，并支持所有相同的选项：

```vue [pages/dashboard.vue]
<script setup lang="ts">
// 自动使用 runtimeConfig 中的 baseURL
const { data: users } = await useApiFetch('/users')
</script>
```

当你传入一个普通对象时，你的使用选项会自动覆盖默认值。当你传入一个函数时，你可以完全控制选项如何合并 – 这意味着你可以按需要组合拦截器、请求头以及其他复杂选项。

在底层，这由一个新的 Nuxt 临时模块驱动，它会扫描你的 composables 目录，并自动为 key 注入注册你的自定义实例 – 因此它们可以像 `useAsyncData` 和 `useFetch` 一样，和 SSR 无缝配合。

`createUseAsyncData` 也提供了同样的模式，用于 `useAsyncData`。

::read-more{to="https://nuxt.zhcndoc.com/docs/api/composables/create-use-async-data"}
::

## 🗺️ Vue Router v5

我们已经升级到 [vue-router v5](https://github.com/vuejs/router)（[#34181](https://github.com/nuxt/nuxt/pull/34181)），并移除了对 `unplugin-vue-router` 的依赖。这是自 Nuxt 3 以来首次重大升级 vue-router，它在底层带来了许多改进。

对大多数应用来说，这应该是一次透明升级。如果你直接使用了 `unplugin-vue-router`，可以将它从依赖中移除。

下一步将是把类型化路由从实验状态中移出。👀

## 💪 `definePageMeta` 中的类型化布局 Props

现在你可以直接从 `definePageMeta` 向布局传递 props 了（[#34262](https://github.com/nuxt/nuxt/pull/34262)）。这意味着你的布局可以按页面参数化，而不需要使用 `provide`/`inject` 或其他变通方案。查看[更新后的文档](https://nuxt.zhcndoc.com/docs/guide/directory-structure/layouts#layout-props)以了解完整细节。

```ts [pages/dashboard.vue]
definePageMeta({
  layout: {
    name: 'panel',
    props: {
      sidebar: true,
      title: 'Dashboard',
    },
  },
})
```

更棒的是 – 这些 props 是**完全类型化**的（[#34409](https://github.com/nuxt/nuxt/pull/34409)）。如果你的布局定义了 props，你在 `definePageMeta` 中就会获得自动补全和类型检查。

```vue [layouts/panel.vue]
<script setup lang="ts">
defineProps<{
  sidebar?: boolean
  title?: string
}>()
</script>
```

::read-more{to="https://nuxt.zhcndoc.com/docs/guide/directory-structure/layouts"}
::

## 🗣️ `useAnnouncer` Composable

新的 `useAnnouncer` composable 和 `<NuxtAnnouncer>` 组件让无障碍支持得到了重大提升（[#34318](https://github.com/nuxt/nuxt/pull/34318)）。虽然 `useRouteAnnouncer` 负责屏幕阅读器的页面导航播报，但许多应用还需要播报**页面内动态变化** – 表单提交、加载状态、搜索结果等等。

::code-group
```vue [app.vue]
<template>
  <NuxtAnnouncer />
  <NuxtRouteAnnouncer />
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>
```

```vue [components/ContactForm.vue]
<script setup lang="ts">
const { polite, assertive } = useAnnouncer()

async function submitForm() {
  try {
    await $fetch('/api/contact', { method: 'POST', body: formData })
    polite('消息发送成功')
  }
  catch (error) {
    assertive('错误：消息发送失败')
  }
}
</script>
```
::

::note
这是我们[无障碍路线图](https://github.com/nuxt/nuxt/issues/23255)的一部分。你不需要在所有地方都使用它 – 对于很多交互来说，把焦点移动到新内容上，或使用原生表单校验就已经足够了。`useAnnouncer` 在内容动态变化但没有相应焦点变化时最有用。
::

::read-more{to="https://nuxt.zhcndoc.com/docs/api/composables/use-announcer"}
::

## 🚀 迁移到 `unrouting`

我们已将 Nuxt 的文件系统路由生成迁移到 [`unrouting`](https://github.com/unjs/unrouting)（[#34316](https://github.com/nuxt/nuxt/pull/34316)），它使用 trie 数据结构来构建路由。冷启动时间大致相同（大型应用约 \~8ms 对 \~6ms），但在不新增/删除页面时，开发服务器变更速度**最高快 28 倍**，即使新增/删除页面时也仍然快约 \~15%。

这也让路由生成更加确定性 – 不再受页面文件顺序影响。

## 🍫 缓存路由的更智能 Payload 处理

当启用了 payload 提取的缓存路由（ISR/SWR）在运行时渲染时，浏览器会立即作为第二个请求获取 `_payload.json` – 这会触发同一页面的完整 SSR 重新渲染。在无服务器环境中，这甚至可能在第一次响应流还未结束时就启动第二个 lambda。

本次发布通过两项改动解决了这个问题（[#34410](https://github.com/nuxt/nuxt/pull/34410)）：

1. 新的 `payloadExtraction: 'client'` 模式会在初始 HTML 响应中内联完整 payload，同时仍然生成 `_payload.json` 供客户端导航使用
2. 运行时内存 LRU payload 缓存，使 `_payload.json` 请求可以在不完整重渲染的情况下被响应

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  experimental: {
    payloadExtraction: 'client',
  },
})
```

::note
`payloadExtraction: 'client'` 将在 `compatibilityVersion: 5` 时成为默认值。运行时缓存对所有用户都已启用。
::

::read-more{to="https://nuxt.zhcndoc.com/docs/guide/going-further/experimental-features#payloadextraction"}
::

## 🍪 `useCookie` 的 `refresh` 选项

如果你使用 cookie 进行会话管理，你大概遇到过这样的问题：需要在不改变 cookie 值的情况下延长其过期时间。新的 `refresh` 选项让这变得很简单（[#33814](https://github.com/nuxt/nuxt/pull/33814)）：

```ts
const session = useCookie('session-id', {
  maxAge: 60 * 60,
  refresh: true,
})

// 每次都会延长过期时间，即使值相同
session.value = session.value
```

::read-more{to="https://nuxt.zhcndoc.com/docs/api/composables/use-cookie"}
::

## ♻️ `useState` 重置为默认值

`useState` 和 `clearNuxtState` 现在支持将状态重置为初始值，而不是清空为 `undefined`（[#33527](https://github.com/nuxt/nuxt/pull/33527)）。这与 `useAsyncData` 的重置处理方式一致，也更符合状态管理的直觉。

```ts
const count = useState('counter', () => 0)
count.value = 42

// 重置为 0（初始值），而不是 undefined
clearNuxtState('counter')
```

::read-more{to="https://nuxt.zhcndoc.com/docs/api/utils/clear-nuxt-state"}
::

## 🕵️‍♂️ 更好的导入保护

受 [TanStack Start](https://tanstack.com/start/latest/docs/framework/react/guide/import-protection) 中功能的启发，导入保护现在会显示**建议**以及问题导入来源的完整**追踪**（[#34454](https://github.com/nuxt/nuxt/pull/34454)）。这让调试为什么仅服务端的导入最终进入了客户端 bundle 变得容易得多。

例如，如果你在组件中不小心从一个服务端路由导入：

![更有用的导入保护错误](https://nuxt.zhcndoc.com/assets/blog/import-protection.png)

追踪会显示导入链（该组件是从一个页面导入的）、精确的代码行，以及如何修复的可操作建议。

我们计划继续改进错误信息。🪵

## 🔮 View Transitions 类型

现在你可以在 Nuxt 的实验性视图过渡支持中定义 [view transition types](https://developer.chrome.com/blog/view-transitions-update-io24#view-transition-types) 了（[#31982](https://github.com/nuxt/nuxt/pull/31982)）。这让你可以针对不同的导航模式使用不同的过渡样式（前进 vs. 后退、标签页 vs. 页面，等等）。

::read-more{to="https://nuxt.zhcndoc.com/docs/getting-started/transitions#view-transitions-api-experimental"}
::

## 💡 改进的 `optimizeDeps` 提示

当 Vite 在运行时发现新的依赖并触发页面刷新时，Nuxt 现在会显示一段清晰、可直接复制粘贴的 `nuxt.config.ts` 片段，用于预构建这些依赖（[#34320](https://github.com/nuxt/nuxt/pull/34320)）。它还会在启动时警告不可解析的条目。

## 🏷️ 规范化的页面组件名称（实验性）

一个新的实验性选项会将页面组件名称规范化，使其与路由名称一致（[#33513](https://github.com/nuxt/nuxt/pull/33513)），这有助于在 devtools 和调试中保持一致性。

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  experimental: {
    normalizeComponentNames: true,
  },
})
```

::read-more{to="https://nuxt.zhcndoc.com/docs/guide/going-further/experimental-features#normalizecomponentnames"}
::

## ⚡ 构建性能分析

有没有想过你的构建时间都花到哪里去了？现在你可以获得 Nuxt 构建的详细性能分解了（[#34468](https://github.com/nuxt/nuxt/pull/34468), [nuxt/cli#1243](https://github.com/nuxt/cli/pull/1243)）：

```bash
nuxt build --profile
```

这会生成一份报告，展示每个构建阶段、模块和打包器插件的耗时、RSS 变化量以及 heap 变化量：

![控制台输出的构建耗时报告](https://nuxt.zhcndoc.com/assets/blog/build-profiler.png)

它还会对单个模块和打包器插件进行分析，方便你快速发现瓶颈。会写出三种输出格式：

- **Chrome Trace** (`.nuxt/perf-trace.json`) – 在 `chrome://tracing` 或 Perfetto 中打开，可查看可视化时间线
- **JSON 报告** (`.nuxt/perf-report.json`) – 便于机器读取的数据，用于长期跟踪
- **CPU profile** (`nuxt-build.cpuprofile`) – 可在 Chrome DevTools 或 VS Code 中打开以查看火焰图

如果想要更详细的信息，可以使用 `--profile=verbose` 在控制台输出更细粒度的时间分解。

::read-more{to="https://nuxt.zhcndoc.com/docs/api/commands/build"}
::

我们会使用这个功能让 Nuxt 变得更快 – 如果你也关心性能，这可能是一个很好的贡献机会！

## 🔥 性能改进

- **模块 ID 解析速度提升 14,000 倍** – 使用单个 `indexOf` + `slice` 替换了 `new URL()` + 正则链 ([#34451](https://github.com/nuxt/nuxt/pull/34451))
- **在开发环境中禁用了 NuxtLink 可见性预取** – 阻止 Vite 在开发过程中不必要地发现并重新加载依赖项 ([#34325](https://github.com/nuxt/nuxt/pull/34325))

## ⬆︎ 升级

我们建议通过以下命令进行升级：

```sh
npx nuxt upgrade --dedupe
```

这将去重你的 lockfile，并帮助确保你拉取到 Nuxt 所依赖的其他依赖项的更新，特别是在 unjs 生态系统中。

::tip
如果你是从旧版本升级，请查看我们的 [升级指南](https://nuxt.zhcndoc.com/docs/getting-started/upgrade)。
::

## 👉 完整发布说明

::read-more{icon="i-simple-icons-github" target="_blank" to="https://github.com/nuxt/nuxt/releases/tag/v4.4.0"}
阅读 Nuxt `v4.4.0` 的完整发布说明。
::

感谢本次发布的所有贡献者！💚


## Sitemap

See the full [sitemap](https://nuxt.zhcndoc.com/sitemap.md) for all pages.
