Nuxt 生命周期
本章的目标是提供框架不同部分的高级概述,包括它们的执行顺序以及它们如何协同工作。
服务器端
在服务器端,针对每个初始请求会执行以下步骤:
步骤 1:设置 Nitro 服务器和 Nitro 插件(仅一次)
Nuxt 由 Nitro 提供支持,这是一个现代服务器引擎。
当 Nitro 启动时,它会初始化并执行位于 /server/plugins
目录下的插件。这些插件可以:
- 捕获并处理应用范围内的错误。
- 注册 Nitro 关闭时执行的钩子。
- 注册请求生命周期事件的钩子,例如修改响应。
步骤 2:Nitro 服务器中间件
在初始化 Nitro 服务器后,每次请求都会执行位于 server/middleware/
目录下的中间件。中间件可用于执行认证、日志记录或请求转换等任务。
步骤 3:初始化 Nuxt 并执行 Nuxt 应用插件
首先创建 Vue 和 Nuxt 实例。之后,Nuxt 执行其服务器插件,包括:
- 内置插件,例如 Vue Router 和
unhead
。 - 位于
plugins/
目录下的自定义插件,包括无后缀的插件(例如myPlugin.ts
)和带有.server
后缀的插件(例如myServerPlugin.server.ts
)。
插件按特定顺序执行,并且可能相互依赖。有关执行顺序和并行性的更多详细信息,请参阅 插件文档。
app:created
钩子,可用于执行额外的逻辑。步骤 4:路由验证
在初始化插件并执行中间件之前,如果在 definePageMeta
函数中定义了 validate
方法,Nuxt 会调用该方法。validate
方法可以是同步或异步的,通常用于验证动态路由参数。
- 如果参数有效,
validate
函数应返回true
。 - 如果验证失败,应返回
false
或一个包含statusCode
和/或statusMessage
的对象以终止请求。
更多信息,请参阅 路由验证文档。
步骤 5:执行 Nuxt 应用中间件
中间件允许您在导航到特定路由之前运行代码,常用于认证、重定向或日志记录等任务。
在 Nuxt 中,有三种类型的中间件:
- 全局路由中间件
- 命名路由中间件
- 匿名(或内联)路由中间件
Nuxt 会在首次进入应用时以及每次路由导航前自动执行全局中间件。命名和匿名中间件仅在页面(路由)元数据中指定的路由上执行,这些元数据在对应的页面组件中定义。
有关每种类型的详细信息和示例,请参阅 中间件文档。
在服务器端进行的任何重定向都会导致向浏览器发送 Location:
头;浏览器随后会对新位置发起新的请求。此时,除非通过 cookie 持久化,否则所有应用状态都将被重置。
步骤 6:设置页面和组件
在此步骤中,Nuxt 初始化页面及其组件,并使用 useFetch
和 useAsyncData
获取所需的任何数据。由于服务器端没有动态更新且不涉及 DOM 操作,因此 Vue 生命周期钩子(如 onBeforeMount
、onMounted
及后续钩子)在 SSR 期间不会被执行。
<script setup>
的根作用域中编写需要清理的副作用代码。例如,使用 setInterval
设置定时器。在仅限客户端的代码中,我们可能会设置一个定时器并在 onBeforeUnmount
或 onUnmounted
中清理它。然而,由于在 SSR 期间卸载钩子永远不会被调用,定时器将一直存在。为避免这种情况,请将副作用代码移到 onMounted
中。步骤 7:渲染并生成 HTML 输出
在所有组件初始化并获取数据后,Nuxt 将组件与 unhead
的设置结合起来,生成完整的 HTML 文档。此 HTML 连同相关数据被发送回客户端,完成 SSR 过程。
app:rendered
钩子。render:html
钩子。此钩子允许您操作生成的 HTML,例如注入额外的脚本或修改元标签。客户端(浏览器)
生命周期的这一部分完全在浏览器中执行,无论您选择了哪种 Nuxt 模式。
步骤 1:初始化 Nuxt 并执行 Nuxt 应用插件
此步骤类似于服务器端执行,包括内置插件和自定义插件。
位于 plugins/
目录下的自定义插件,例如无后缀的插件(例如 myPlugin.ts
)和带有 .client
后缀的插件(例如 myClientPlugin.client.ts
),会在客户端执行。
app:created
钩子,可用于执行额外的逻辑。步骤 2:路由验证
此步骤与服务器端执行相同,包括在 definePageMeta
函数中定义的 validate
方法。
步骤 3:执行 Nuxt 应用中间件
Nuxt 中间件在服务器端和客户端均运行。如果您希望某些代码在特定环境中运行,可以通过使用 import.meta.client
(客户端)和 import.meta.server
(服务器端)进行拆分。
步骤 4:挂载 Vue 应用和水合
调用 app.mount('#__nuxt')
将 Vue 应用挂载到 DOM。如果应用使用 SSR 或 SSG 模式,Vue 会执行水合步骤,使客户端应用具有交互性。在水合期间,Vue 会重新创建应用(不包括 服务器组件),将每个组件与其对应的 DOM 节点匹配,并附加 DOM 事件监听器。
为确保正确水合,服务器端和客户端的数据一致性非常重要。对于 API 请求,建议使用 useAsyncData
、useFetch
或其他 SSR 友好的组合式函数。这些方法可确保在服务器端获取的数据在水合期间被重用,避免重复请求。任何新请求都应在水合后触发,以防止水合错误。
app:beforeMount
钩子。app:mounted
钩子。步骤 5:Vue 生命周期
与服务器端不同,浏览器会执行完整的 Vue 生命周期。