---
title: "Nuxt 生命周期"
description: "理解 Nuxt 应用的生命周期可以帮助你更深入地了解框架的运行方式，尤其是针对服务器端和客户端渲染。"
canonical_url: "https://nuxt.zhcndoc.com/docs/4.x/guide/concepts/nuxt-lifecycle"
---
# Nuxt 生命周期

> 理解 Nuxt 应用的生命周期可以帮助你更深入地了解框架的运行方式，尤其是针对服务器端和客户端渲染。

本章的目标是提供框架中不同部分的高级概览，讲解它们的执行顺序以及它们如何协同工作。

## Server 生命周期

在服务器端，每个初始请求到应用时，都会执行以下步骤：

::steps
### 服务器插件 :badge[once]{color="info" .align-middle}

Nuxt 由 [Nitro](https://nitro.build/) 驱动，这是一个现代的服务器引擎。

当 Nitro 启动时，它会初始化并执行 [`/server/plugins`](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/server#server-plugins) 目录下的插件。这些插件可以：

- 捕获并处理应用级错误。
- 注册在 Nitro 关闭时执行的钩子。
- 为请求生命周期事件注册钩子，例如修改响应。

  :::callout{icon="i-lucide-lightbulb"}
  Nitro 插件仅在服务器启动时执行一次。在无服务器（serverless）环境中，服务器会在每个传入请求时启动，Nitro 插件也会随之执行。然而，这些插件的执行不会被等待。
  :::

  :::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/directory-structure/server#server-plugins"}
  :::

### 服务器中间件

在初始化 Nitro 服务器之后，`server/middleware/` 下的中间件会在每个请求上执行。中间件可用于身份认证、日志记录或请求转换等任务。

  :::warning
  从中间件返回一个值将终止请求并将返回值作为响应发送。通常应避免这种行为以确保请求得到正确处理！
  :::

  :::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/directory-structure/server#server-middleware"}
  :::

### 应用插件

Vue 和 Nuxt 实例首先被创建。随后，Nuxt 执行其应用插件。这包括：

- 内置插件，如 Vue Router 和 `unhead`。
- 位于 `app/plugins/` 目录下的自定义插件，包括无后缀（例如 `myPlugin.ts`）和带 `.server` 后缀（例如 `myServerPlugin.server.ts`）的插件。

插件按特定顺序执行，并且可能相互依赖。有关执行顺序和并行性的更多详情，请参阅[插件文档](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/plugins)。

  :::callout{icon="i-lucide-lightbulb"}
  此步骤之后，Nuxt 会调用 [`app:created`](https://nuxt.zhcndoc.com/docs/4.x/api/advanced/hooks#app-hooks-runtime) 钩子，可用于执行其他逻辑。
  :::

  :::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/plugins"}
  :::

### 路由验证

在初始化插件并且执行页面中间件之前，如果在 `definePageMeta` 中定义了 `validate` 方法，Nuxt 会调用该方法。`validate` 方法可以是同步或异步的，通用于验证动态路由参数。

- 如果参数有效，`validate` 函数应返回 `true`。
- 如果验证失败，应返回 `false` 或包含 `status` 和/或 `statusText` 的对象以终止请求。

更多信息，请参阅[路由验证文档](https://nuxt.zhcndoc.com/docs/4.x/getting-started/routing#route-validation)。

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

### 应用中间件

中间件允许你在路由跳转前运行代码，常用于身份认证、重定向或日志记录等任务。

在 Nuxt 中，存在三种类型的中间件：

- **全局路由中间件**
- **命名路由中间件**
- **匿名（或内联）路由中间件**

Nuxt 会在初始页面加载时（服务器端和客户端均执行）以及之后任意客户端导航之前执行所有全局中间件。命名和匿名中间件仅在对应页面组件的路由元信息 `middleware` 属性指定的路由上执行。

有关每种类型的详情和示例，请参阅[中间件文档](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/middleware)。

在服务器端发生重定向时，会向浏览器发送 `Location:` 头，浏览器随后会发起对该新地址的全新请求。此时所有应用状态都会被重置，除非用 Cookie 进行了持久化。

  :::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/middleware"}
  :::

### 页面与组件

Nuxt 在此步骤中渲染页面及其组件，并使用 `useFetch` 和 `useAsyncData` 获取所需数据。由于服务器端不存在动态更新也不会进行 DOM 操作，Vue 生命周期钩子如 `onBeforeMount`、`onMounted` 及后续钩子在 SSR 期间**不会**被执行。

默认情况下，为了提升性能，Vue 会在 SSR 期间暂停依赖追踪。

  :::callout{icon="i-lucide-lightbulb"}
  服务器端无响应式支持，因为 Vue SSR 会将应用自顶向下渲染成静态 HTML，渲染完成后无法修改已渲染内容。
  :::

  :::important
  应避免在 `<script setup>` 根作用域中放置需要清理的副作用代码。例如使用 `setInterval` 创建的定时器。客户端代码中通常在 `onBeforeUnmount` 或 `onUnmounted` 钩子销毁这些定时器，但 SSR 期间卸载钩子不会被调用，定时器会永久存在。为避免此问题，应将副作用代码移至 `onMounted` 中。
  :::

  :::tip{icon="i-lucide-video" to="https://youtu.be/dZSNW07sO-A" target="_blank"}
  观看 Daniel Roe 讲解服务器渲染和全局状态的视频。
  :::

### HTML 输出

在获取全部所需数据并渲染组件后，Nuxt 会将渲染结果与 `unhead` 设置结合，生成完整的 HTML 文档。然后将该 HTML 及关联数据发送给客户端，完成 SSR 过程。

  :::callout{icon="i-lucide-lightbulb"}
  将 Vue 应用渲染为 HTML 后，Nuxt 会调用 [`app:rendered`](https://nuxt.zhcndoc.com/docs/4.x/api/advanced/hooks#app-hooks-runtime) 钩子。
  :::

  :::callout{icon="i-lucide-lightbulb"}
  在最终确定并发送 HTML 之前，Nitro 会调用 [`render:html`](https://nuxt.zhcndoc.com/docs/4.x/api/advanced/hooks#nitro-app-hooks-runtime-server-side) 钩子。此钩子允许你修改生成的 HTML，例如注入其他脚本或修改 meta 标签。
  :::
::

## 客户端生命周期

此部分的生命周期完全在浏览器中执行，无论你选择的是哪种 Nuxt 模式。

::steps
### 应用插件

此步骤与服务器端类似，包含内置插件和自定义插件。

`app/plugins/` 目录下的自定义插件，如无后缀（`myPlugin.ts`）和带 `.client` 后缀（`myClientPlugin.client.ts`）的，会在客户端执行。

  :::callout{icon="i-lucide-lightbulb"}
  此步骤之后，Nuxt 会调用 [`app:created`](https://nuxt.zhcndoc.com/docs/4.x/api/advanced/hooks#app-hooks-runtime) 钩子，可用于执行其他逻辑。
  :::

  :::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/plugins"}
  :::

### 路由验证

此步骤与服务器端相同，执行在 `definePageMeta` 中定义的 `validate` 方法。

### 应用中间件

Nuxt 中间件在服务器和客户端都会运行。如果你希望某些代码只在特定环境中运行，可以使用 `import.meta.client`（仅客户端）和 `import.meta.server`（仅服务器）区分代码。

  :::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/middleware#when-middleware-runs"}
  :::

### 挂载 Vue 应用并水合

调用 `app.mount('#__nuxt')` 会将 Vue 应用挂载到 DOM。如果应用使用 SSR 或 SSG 模式，Vue 会执行水合步骤，使客户端应用变得可交互。在水合期间，Vue 会重新创建应用（不包括 [Server Components](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/components#server-components)），将每个组件与对应的 DOM 节点匹配，并附加 DOM 事件监听器。

为确保水合正确，需要保持服务器端和客户端数据一致。针对 API 请求，推荐使用 `useAsyncData`、`useFetch` 或其他 SSR 友好的组合式函数。这些方法确保服务器端获取的数据在水合期间可以复用，避免重复请求。任何新的请求应在水合完成后触发，以防止水合失败。

  :::callout{icon="i-lucide-lightbulb"}
  挂载 Vue 应用之前，Nuxt 会调用 [`app:beforeMount`](https://nuxt.zhcndoc.com/docs/4.x/api/advanced/hooks#app-hooks-runtime) 钩子。
  :::

  :::callout{icon="i-lucide-lightbulb"}
  挂载 Vue 应用之后，Nuxt 会调用 [`app:mounted`](https://nuxt.zhcndoc.com/docs/4.x/api/advanced/hooks#app-hooks-runtime) 钩子。
  :::

### Vue 生命周期

与服务器端不同，浏览器会执行完整的 [Vue 生命周期](https://vuejs.org/guide/essentials/lifecycle)。
::


## Sitemap

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