Nuxt 生命周期
本章的目标是从高层次概述框架的各个部分、它们的执行顺序以及它们如何协同工作。
¥The goal of this chapter is to provide a high-level overview of the different parts of the framework, their execution order, and how they work together.
服务器
¥Server
在服务器上,对应用的每个初始请求都会执行以下步骤:
¥On the server, the following steps are executed for every initial request to your application:
步骤 1:设置 Nitro 服务器和 Nitro 插件(一次)
¥Step 1: Setup Nitro Server and Nitro Plugins (Once)
Nuxt 由现代服务器引擎 Nitro 提供支持。
¥Nuxt is powered by Nitro, a modern server engine.
Nitro 启动时,会初始化并执行 /server/plugins
目录下的插件。这些插件可以:
¥When Nitro starts, it initializes and executes the plugins under the /server/plugins
directory. These plugins can:
- 捕获并处理应用范围的错误。
- 注册在 Nitro 关闭时执行的钩子。
- 注册用于请求生命周期事件(例如修改响应)的钩子。
步骤 2:Nitro 服务器中间件
¥Step 2: Nitro Server Middleware
初始化 Nitro 服务器后,每个请求都会执行 server/middleware/
下的中间件。中间件可用于身份验证、日志记录或请求转换等任务。
¥After initializing the Nitro server, middleware under server/middleware/
is executed for every request. Middleware can be used for tasks such as authentication, logging, or request transformation.
步骤 3:初始化 Nuxt 并执行 Nuxt 应用插件
¥Step 3: Initialize Nuxt and Execute Nuxt App Plugins
首先会创建 Vue 和 Nuxt 实例。之后,Nuxt 会执行其服务器插件。这包括:
¥The Vue and Nuxt instances are created first. Afterward, Nuxt executes its server plugins. This includes:
- 内置插件,例如 Vue Router 和
unhead
。 - 位于
plugins/
目录中的自定义插件,包括不带后缀的插件(例如myPlugin.ts
)和带.server
后缀的插件(例如myServerPlugin.server.ts
)。
插件按特定顺序执行,并且可能相互依赖。更多详情,请参阅 插件文档。
¥Plugins execute in a specific order and may have dependencies on one another. For more details, including execution order and parallelism, refer to the Plugins documentation.
app:created
钩子,该钩子可用于执行其他逻辑。¥After this step, Nuxt calls the app:created
hook, which can be used to execute additional logic.步骤 4:路由验证
¥Step 4: Route Validation
在初始化插件之后、执行中间件之前,如果 validate
方法在 definePageMeta
函数中定义,Nuxt 会调用该方法。validate
方法可以是同步的,也可以是异步的,通常用于验证动态路由参数。
¥After initializing plugins and before executing middleware, Nuxt calls the validate
method if it is defined in the definePageMeta
function. The validate
method, which can be synchronous or asynchronous, is often used to validate dynamic route parameters.
- 如果参数有效,
validate
函数应该返回true
。 - 如果验证失败,它应该返回
false
或包含statusCode
和/或statusMessage
的对象以终止请求。
更多信息,请访问 路由验证文档。
¥For more information, see the Route Validation documentation.
步骤 5:执行 Nuxt 应用中间件
¥Step 5: Execute Nuxt App Middleware
中间件允许你在导航到特定路由之前运行代码。它通常用于身份验证、重定向或日志记录等任务。
¥Middleware allows you to run code before navigating to a particular route. It is often used for tasks such as authentication, redirection, or logging.
Nuxt 中有三种类型的中间件:
¥In Nuxt, there are three types of middleware:
- 全局路由中间件
- 命名路由中间件
- 匿名(或内联)路由中间件
Nuxt 会在首次进入应用以及每次路由导航之前自动执行全局中间件。命名中间件和匿名中间件仅在相应页面组件中定义的 page(route) 元属性的 middleware 属性中指定的路由上执行。
¥Nuxt automatically executes global middleware for first time enter to the application and every time before route navigation. Named and anonymous middleware are executed only on the routes specified in the middleware property of the page(route) meta defined in the corresponding page components.
有关每种类型和示例的详细信息,请参阅 中间件文档。
¥For details about each type and examples, see the Middleware documentation.
服务器上的任何重定向都会导致向浏览器发送 Location:
标头;然后浏览器会向这个新位置发出新的请求。发生这种情况时,所有应用状态都将被重置,除非已将其持久化到 Cookie 中。
¥Any redirection on the server will result in a Location:
header being sent to the browser; the browser then makes a fresh request to this new location. All application state will be reset when this happens, unless persisted in a cookie.
步骤 6:设置页面和组件
¥Step 6: Setup Page and Components
Nuxt 在此步骤中初始化页面及其组件,并使用 useFetch
和 useAsyncData
获取任何所需数据。由于服务器端没有动态更新且没有 DOM 操作,因此 Vue 生命周期钩子(例如 onBeforeMount
、onMounted
及其后续钩子)在服务器渲染期间不会执行。
¥Nuxt initializes the page and its components during this step and fetches any required data with useFetch
and useAsyncData
. Since there are no dynamic updates and no DOM operations occur on the server, Vue lifecycle hooks such as onBeforeMount
, onMounted
, and subsequent hooks are NOT executed during SSR.
<script setup>
的根作用域中编写会产生副作用且需要清理的代码。例如,在 setInterval
中设置计时器就是此类副作用的一个例子。在纯客户端代码中,我们可能会设置一个计时器,然后在 onBeforeUnmount
或 onUnmounted
中将其拆除。但是,由于卸载钩子在 SSR 期间永远不会被调用,因此计时器将永远存在。为了避免这种情况,请将会产生副作用的代码移到 onMounted
中。步骤 7:渲染并生成 HTML 输出
¥Step 7: Render and Generate HTML Output
所有组件初始化并获取数据后,Nuxt 会将组件与 unhead
中的设置相结合,生成完整的 HTML 文档。此 HTML 以及相关数据将发送回客户端以完成 SSR 流程。
¥After all components are initialized and data is fetched, Nuxt combines the components with settings from unhead
to generate a complete HTML document. This HTML, along with the associated data, is sent back to the client to complete the SSR process.
app:rendered
钩子。¥After rendering the Vue application to HTML, Nuxt calls the app:rendered
hook.render:html
钩子。此钩子允许你操作生成的 HTML,例如注入其他脚本或修改元标记。¥Before finalizing and sending the HTML, Nitro will call the render:html
hook. This hook allows you to manipulate the generated HTML, such as injecting additional scripts or modifying meta tags.客户端(浏览器)
¥Client (browser)
无论你选择哪种 Nuxt 模式,生命周期的这一部分都完全在浏览器中执行。
¥This part of the lifecycle is fully executed in the browser, no matter which Nuxt mode you've chosen.
步骤 1:初始化 Nuxt 并执行 Nuxt 应用插件
¥Step 1: Initialize Nuxt and Execute Nuxt App Plugins
此步骤类似于服务器端执行,包含内置插件和自定义插件。
¥This step is similar to the server-side execution and includes both built-in and custom plugins.
plugins/
目录中的自定义插件,例如没有后缀(例如 myPlugin.ts
)和带有 .client
后缀(例如 myClientPlugin.client.ts
)的插件,在客户端执行。
¥Custom plugins in the plugins/
directory, such as those without a suffix (e.g., myPlugin.ts
) and with the .client
suffix (e.g., myClientPlugin.client.ts
), are executed on the client side.
app:created
钩子,该钩子可用于执行其他逻辑。¥After this step, Nuxt calls the app:created
hook, which can be used to execute additional logic.步骤 2:路由验证
¥Step 2: Route Validation
此步骤与服务器端执行相同,并且如果 definePageMeta
函数中定义了 validate
方法,则包含该方法。
¥This step is the same as the server-side execution and includes the validate
method if defined in the definePageMeta
function.
步骤 3:执行 Nuxt 应用中间件
¥Step 3: Execute Nuxt App Middleware
Nuxt 中间件在服务器和客户端上运行。如果你希望某些代码在特定环境中运行,请考虑将其拆分,使用 import.meta.client
表示客户端,import.meta.server
表示服务器。
¥Nuxt middleware runs on both the server and the client. If you want certain code to run in specific environments, consider splitting it by using import.meta.client
for the client and import.meta.server
for the server.
步骤 4:挂载 Vue 应用和 Hydration
¥Step 4: Mount Vue Application and Hydration
调用 app.mount('#__nuxt')
会将 Vue 应用挂载到 DOM。如果应用使用 SSR 或 SSG 模式,Vue 会执行 hydrated 步骤,使客户端应用具有交互性。在 hydration 过程中,Vue 会重新创建应用(不包括 服务器组件),将每个组件与其对应的 DOM 节点匹配,并附加 DOM 事件监听器。
¥Calling app.mount('#__nuxt')
mounts the Vue application to the DOM. If the application uses SSR or SSG mode, Vue performs a hydration step to make the client-side application interactive. During hydration, Vue recreates the application (excluding Server Components), matches each component to its corresponding DOM nodes, and attaches DOM event listeners.
为了确保正确数据融合,保持服务器和客户端数据之间的一致性非常重要。对于 API 请求,建议使用 useAsyncData
、useFetch
或其他支持 SSR 的组合项。这些方法确保在服务器端获取的数据在水合过程中被重用,从而避免重复请求。任何新的请求都应该在 hydration 之后触发,以防止 hydration 错误。
¥To ensure proper hydration, it's important to maintain consistency between the data on the server and the client. For API requests, it is recommended to use useAsyncData
, useFetch
, or other SSR-friendly composables. These methods ensure that the data fetched on the server side is reused during hydration, avoiding repeated requests. Any new requests should only be triggered after hydration, preventing hydration errors.
app:beforeMount
钩子。¥Before mounting the Vue application, Nuxt calls the app:beforeMount
hook.app:mounted
钩子。¥After mounting the Vue application, Nuxt calls the app:mounted
hook.步骤 5:Vue 生命周期
¥Step 5: Vue Lifecycle
与服务器不同,浏览器会执行完整的 Vue 生命周期 操作。
¥Unlike on the server, the browser executes the full Vue lifecycle.