---
title: "组件选项"
description: "了解如何将 Nuxt 2 组件选项迁移到 Nuxt 3 的组合式函数。"
canonical_url: "https://nuxt.zhcndoc.com/docs/4.x/migration/component-options"
---
# 组件选项

> 了解如何将 Nuxt 2 组件选项迁移到 Nuxt 3 的组合式函数。

## `asyncData` 和 `fetch`

Nuxt 3 提供了用于[从 API 获取数据](https://nuxt.zhcndoc.com/docs/4.x/getting-started/data-fetching)的新选项。

<!-- TODO: 介绍 <script setup> -->

<!-- TODO: 提及 asyncData 的兼容性 -->

### 同构 Fetch

在 Nuxt 2 中你可能会使用 `@nuxtjs/axios` 或 `@nuxt/http` 来获取数据，或者直接使用被 polyfill 的全局 `fetch`。

在 Nuxt 3 中，你可以使用全局可用的 `fetch` 方法，它的 API 与 [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) 相同；也可以使用 [`$fetch`](https://nuxt.zhcndoc.com/docs/4.x/api/utils/dollarfetch) 方法，该方法使用了 [unjs/ofetch](https://github.com/unjs/ofetch)。它有许多优点，包括：

1. 如果在服务器上运行，它会智能地处理[直接 API 调用](https://nuxt.zhcndoc.com/docs/4.x/guide/concepts/server-engine#direct-api-calls)；如果在客户端上运行，则会向你的 API 发起客户端调用。（它也可以处理对第三方 API 的调用。）
2. 并且，它提供了一些便捷功能，包括自动解析响应和将数据序列化为字符串等。

你可以阅读更多关于[直接 API 调用](https://nuxt.zhcndoc.com/docs/4.x/guide/concepts/server-engine#direct-api-calls)或[获取数据](https://nuxt.zhcndoc.com/docs/4.x/getting-started/data-fetching)的内容。

### 组合式函数

Nuxt 3 提供了用于获取数据的新组合式函数：[`useAsyncData`](https://nuxt.zhcndoc.com/docs/4.x/api/composables/use-async-data) 和 `useFetch`。它们各自都有“惰性”变体（`useLazyAsyncData` 和 `useLazyFetch`），不会阻塞客户端导航。

在 Nuxt 2 中，你会在组件中使用类似下面的语法来获取数据：

```ts
export default {
  async asyncData ({ params, $http }) {
    const post = await $http.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
    return { post }
  },
  // or alternatively
  fetch () {
    this.post = await $http.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
  },
}
```

在你的方法和模板中，你可以像使用组件提供的其他数据一样使用 `post` 变量。

在 Nuxt 3 中，你可以在 `setup()` 方法或 `<script setup>` 标签中使用组合式函数来执行此数据获取：

```vue
<script setup lang="ts">
// Define params wherever, through `defineProps()`, `useRoute()`, etc.
const { data: post, refresh } = await useAsyncData('post', () => $fetch(`https://api.nuxtjs.dev/posts/${params.id}`))
// Or instead - useFetch is a convenience wrapper around useAsyncData when you're just performing a simple fetch
const { data: post, refresh } = await useFetch(`https://api.nuxtjs.dev/posts/${params.id}`)
</script>
```

你现在可以在 Nuxt 3 的模板中使用 `post`，或调用 `refresh` 来更新数据。

::note
尽管名称相似，[`useFetch`](https://nuxt.zhcndoc.com/docs/4.x/api/composables/use-fetch) 并不能直接替代 `fetch()` 钩子。相反，[`useAsyncData`](https://nuxt.zhcndoc.com/docs/4.x/api/composables/use-async-data) 可以替代这两个钩子，而且可定制性更高；它不仅仅能从端点获取数据。[`useFetch`](https://nuxt.zhcndoc.com/docs/4.x/api/composables/use-fetch) 是 [`useAsyncData`](https://nuxt.zhcndoc.com/docs/4.x/api/composables/use-async-data) 的便捷封装，用于从端点获取数据。
::

### 迁移

1. 在页面或组件中，将 `asyncData` 钩子替换为 [`useAsyncData`](https://nuxt.zhcndoc.com/docs/4.x/api/composables/use-async-data) 或 [`useFetch`](https://nuxt.zhcndoc.com/docs/4.x/api/composables/use-fetch)。
2. 在组件中，将 `fetch` 钩子替换为 [`useAsyncData`](https://nuxt.zhcndoc.com/docs/4.x/api/composables/use-async-data) 或 [`useFetch`](https://nuxt.zhcndoc.com/docs/4.x/api/composables/use-fetch)。

## `head`

::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/migration/meta"}
::

## `key`

现在，你可以在 [`definePageMeta`](https://nuxt.zhcndoc.com/docs/4.x/api/utils/define-page-meta) 编译器宏中定义 key。

```diff [app/pages/index.vue]
- <script>
- export default {
-   key: 'index'
-   // or a method
-   // key: route => route.fullPath
- }
+ <script setup>
+ definePageMeta({
+   key: 'index'
+   // or a method
+   // key: route => route.fullPath
+ })
</script>
```

## `layout`

::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/migration/pages-and-layouts"}
::

## `loading`

此功能在 Nuxt 3 中尚不受支持。

## `middleware`

::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/migration/plugins-and-middleware"}
::

## `scrollToTop`

Nuxt 3 中尚不支持此功能。如果你想覆盖 `vue-router` 的默认滚动行为，可以在 `~/router.options.ts` 中进行设置（更多信息请参阅[文档](https://nuxt.zhcndoc.com/docs/4.x/guide/recipes/custom-routing#router-options)）。
与 `key` 类似，在 [`definePageMeta`](https://nuxt.zhcndoc.com/docs/4.x/api/utils/define-page-meta) 编译器宏中指定它。

```diff [app/pages/index.vue]
- <script>
- export default {
-   scrollToTop: false
- }
+ <script setup>
+ definePageMeta({
+   scrollToTop: false
+ })
</script>
```

## `transition`

::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/getting-started/transitions"}
::

## `validate`

Nuxt 3 中的 validate 钩子只接受单个参数，即 `route`。与 Nuxt 2 一样，你可以返回布尔值。如果返回 false 且无法找到其他匹配项，则会导致 404。你也可以直接返回带有 `statusCode`/`statusMessage` 的对象以立即响应错误（不会检查其他匹配项）。

```diff [app/pages/users/[id\\].vue]
- <script>
- export default {
-   async validate({ params }) {
-     return /^\d+$/.test(params.id)
-   }
- }
+ <script setup>
+ definePageMeta({
+   validate: async (route) => {
+     const nuxtApp = useNuxtApp()
+     return /^\d+$/.test(route.params.id)
+   }
+ })
  </script>
```

## `watchQuery`

Nuxt 3 中不支持此功能。相反，你可以直接使用一个 watcher 来触发数据的重新获取。

```vue [app/pages/users/[id\\].vue]
<script setup lang="ts">
const route = useRoute()
const { data, refresh } = await useFetch('/api/user')
watch(() => route.query, () => refresh())
</script>
```


## Sitemap

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