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

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

## `asyncData` 和 `fetch`

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

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

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

### 同构 Fetch

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

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

1. 如果在服务器上运行，它会“智能地”处理[直接 API 调用](https://nuxt.zhcndoc.com/docs/3.x/guide/concepts/server-engine#direct-api-calls)；如果在客户端上运行，则会向你的 API 发起客户端调用。（它也可以处理对第三方 API 的调用。）

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

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

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

Nuxt 3 提供了用于数据获取的新组合式函数：[`useAsyncData`](https://nuxt.zhcndoc.com/docs/3.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 }
  },
  // 或者
  fetch () {
    this.post = await $http.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
  },
}
```

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

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

```vue
<script setup lang="ts">
// 通过 `defineProps()`、`useRoute()` 等定义 params
const { data: post, refresh } = await useAsyncData('post', () => $fetch(`https://api.nuxtjs.dev/posts/${params.id}`))
// 或者 - useFetch 是 useAsyncData 的一个简便封装，适合简单的数据获取
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/3.x/api/composables/use-fetch) 并不是 `fetch()` 钩子的直接替代方案。相反，[`useAsyncData`](https://nuxt.zhcndoc.com/docs/3.x/api/composables/use-async-data) 可以替代这两个钩子，并且更具可定制性；它不仅仅只能从端点获取数据。[`useFetch`](https://nuxt.zhcndoc.com/docs/3.x/api/composables/use-fetch) 是 [`useAsyncData`](https://nuxt.zhcndoc.com/docs/3.x/api/composables/use-async-data) 的便捷封装，用于从端点获取数据。
::

### 迁移步骤

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

## `head`

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

## `key`

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

```diff [pages/index.vue]
- <script>
- export default {
-   key: 'index'
-   // 或一个方法
-   // key: route => route.fullPath
- }
+ <script setup>
+ definePageMeta({
+   key: 'index'
+   // 或一个方法
+   // key: route => route.fullPath
+ })
</script>
```

## `layout`

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

## `loading`

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

## `middleware`

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

## `scrollToTop`

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

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

## `transition`

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

## `validate`

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

```diff [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 中不支持。在 Nuxt 3 中，你可以直接使用监听器来触发数据刷新。

```vue [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.
