---
title: "Nuxt 3.17"
description: "Nuxt 3.17 已发布——带来了 async data 层的重大重构、一个新的内置组件、更好的警告以及性能改进！"
canonical_url: "https://nuxt.zhcndoc.com/blog/v3-17"
---
# Nuxt 3.17

> Nuxt 3.17 已发布——带来了 async data 层的重大重构、一个新的内置组件、更好的警告以及性能改进！

## 📊 数据获取改进

Nuxt 的数据获取层进行了重大重组，带来了对 `useAsyncData` 和 `useFetch` 的显著改进。

尽管我们旨在保持向后兼容，并将重大变更置于 `experimental.granularCachedData` 标志之下（默认禁用），但我们建议在升级后彻底测试您的应用。如果您依赖于在卸载使用 `useAsyncData` 的组件后缓存数据永远可用，您还可以禁用 `experimental.purgeCachedData` 以恢复到以前的行为。

::read-more{to="https://github.com/nuxt/nuxt/pull/31373" target="_blank"}
阅读原始 PR 以获取完整详情。
::

### 跨组件的一致数据

现在所有使用相同键的 `useAsyncData` 或 `useFetch` 调用共享底层 ref，确保应用程序跨组件的一致性：

```vue
<!-- ComponentA.vue -->
<script setup>
const { data: users, pending } = useAsyncData('users', fetchUsers)
</script>

<!-- ComponentB.vue -->
<script setup>
// 这将引用与 ComponentA 相同的数据状态
const { data: users, status } = useAsyncData('users', fetchUsers)
// 当任一组件刷新数据时，两个组件都会保持一致更新
</script>
```

这解决了组件可能存在不一致数据状态的各种问题。

### 响应式键

现在您可以使用计算的 refs、普通 refs 或获取函数作为键：

```ts
const userId = ref('123')
const { data: user } = useAsyncData(
  computed(() => `user-${userId.value}`),
  () => fetchUser(userId.value)
)

// 更改 userId 将自动触发新的数据获取
// 如果没有其他组件在使用旧数据，则会清除旧数据
userId.value = '456'
```

### 优化数据重新获取

多个组件监视相同数据源时，当依赖项更改时现在只会触发一次数据获取：

```ts
// 在多个组件中：
const { data } = useAsyncData(
  'users', 
  () => $fetch(`/api/users?page=${route.query.page}`),
  { watch: [() => route.query.page] }
)

// 当 route.query.page 更改时，仅会发生一次获取操作
// 所有使用此键的组件将同时更新
```

## 🎭 内置 Nuxt 组件

### `<NuxtTime>` - 安全时间显示的新组件

我们添加了一个新的 `<NuxtTime>` 组件用于 SSR 安全的时间显示，该组件解决了处理日期时的水合不匹配问题 ([#31876](https://github.com/nuxt/nuxt/pull/31876))：

```vue
<template>
  <NuxtTime :datetime="Date.now()" />
</template>
```

该组件接受多种时间格式，并优雅地处理客户端和服务器渲染。

### 增强的 `<NuxtErrorBoundary>`

`<NuxtErrorBoundary>` 组件已转变为单文件组件，现在从组件中暴露 `error` 和 `clearError` - 以及错误插槽类型，给您提供更大的能力在模板中处理错误，以及通过 `useTemplateRef` 处理错误 ([#31847](https://github.com/nuxt/nuxt/pull/31847))：

```vue
<NuxtErrorBoundary @error="handleError">
  <template #error="{ error, clearError }">
    <div>
      <p>{{ error.message }}</p>
      <button @click="clearError">重试</button>
    </div>
  </template>
  
  <!-- 可能会出错的内容 -->
  <MyComponent />
</NuxtErrorBoundary>
```

## 🔗 路由改进

`<NuxtLink>` 现在接受 `trailingSlash` 属性，让您对 URL 格式有更多控制 ([#31820](https://github.com/nuxt/nuxt/pull/31820))：

```vue
<NuxtLink to="/about" trailing-slash>关于</NuxtLink>
<!-- 将渲染 <a href="/about/"> -->
```

## 🔄 加载指示器自定义

现在您可以直接在组件上用新属性自定义加载指示器 ([#31532](https://github.com/nuxt/nuxt/pull/31532))：

- `hideDelay`: 控制在隐藏加载条前等待多长时间
- `resetDelay`: 控制在重置加载指示器状态前等待多长时间

```vue
<template>
  <NuxtLoadingIndicator :hide-delay="500" :reset-delay="300" />
</template>
```

## 📚 文档作为包

Nuxt 文档现在作为 npm 包可用！您可以安装 `@nuxt/docs` 以访问用于构建文档网站的原始 markdown 和 YAML 内容 ([#31353](https://github.com/nuxt/nuxt/pull/31353))。

## 💻 开发者体验改进

我们添加了几个警告来帮助捕捉常见错误：

- 当服务器组件没有根元素时的警告 [#31365](https://github.com/nuxt/nuxt/pull/31365)
- 当使用保留的 `runtimeConfig.app` 命名空间时的警告 [#31774](https://github.com/nuxt/nuxt/pull/31774)
- 当覆盖核心自动导入预设时的警告 [#29971](https://github.com/nuxt/nuxt/pull/29971)
- 当在一个文件中多次使用 `definePageMeta` 时的错误 [#31634](https://github.com/nuxt/nuxt/pull/31634)

## 🔌 模块开发增强

模块作者会很高兴地知道：

- 新的 `experimental.enforceModuleCompatibility` 允许 Nuxt 在加载不兼容的模块时抛出错误 ([#31657](https://github.com/nuxt/nuxt/pull/31657))。它将在 Nuxt v4 中默认启用。
- 现在可以通过 `addComponentExports` 自动注册从文件导出的每个组件 [#27155](https://github.com/nuxt/nuxt/pull/27155)

## 🔥 性能改进

已进行多项性能改进：

- 切换到 `tinyglobby` 以加快文件 Glob 操作 [#31668](https://github.com/nuxt/nuxt/pull/31668)
- 排除 `.data` 目录的类型检查以加快构建速度 [#31738](https://github.com/nuxt/nuxt/pull/31738)
- 通过提升 `purgeCachedData` 检查改进树摇 [#31785](https://github.com/nuxt/nuxt/pull/31785)

## ✅ 升级

我们推荐的升级方法是运行：

```sh
npx nuxi@latest upgrade --dedupe
```

这将刷新您的锁定文件并拉取所有 Nuxt 依赖的最新版本，特别是来自 unjs 生态系统的依赖。

## 完整发布说明

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

非常感谢所有参与此次发布的每一个人。❤️


## Sitemap

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