nuxt生命周期
这正是理解 Nuxt 的“任督二脉”。如果你搞不清楚代码在哪运行,就会遇到各种奇葩错误,比如“window is not defined”或者“为什么我的 Console 打印在黑框框(终端)里而不是

nuxt生命周期

发布时间:2026-04-21 (48分钟前)

这正是理解 Nuxt 的“任督二脉”。如果你搞不清楚代码在哪运行,就会遇到各种奇葩错误,比如“window is not defined”或者“为什么我的 Console 打印在黑框框(终端)里而不是浏览器里”。

同构渲染

我们要聊的是**“同构渲染(Isomorphic Rendering)”**的艺术。

也常被称为通用渲染(Universal Rendering),是指代码可以同时运行在服务器端和客户端的能力。

同构渲染的工作模式可以拆解为两个阶段:

第一阶段:服务端渲染 (SSR)

当你第一次访问页面(或刷新页面)时:

  1. 服务器执行 Vue 代码,将数据填充进组件。
  2. 生成完整的HTML 字符串
  3. 将 HTML 直接发送给浏览器。
  • 好处: 用户能立即看到内容,SEO 友好(搜索引擎爬虫能抓取到完整的 HTML)。

第二阶段:客户端激活 (Hydration)

HTML 到达浏览器后:

  1. 浏览器下载并执行项目中的 JavaScript。
  2. Vue 会在浏览器中重新运行,接管服务器生成的静态 HTML,使其恢复响应式(比如绑定点击事件、表单交互)。
  3. 这个过程被称为**“注水” (Hydration)**。
  • 好处: 页面后续的跳转不再需要请求服务器生成 HTML,而是像 SPA 一样丝滑,只请求数据。

怎么判断当前环境?

如果你有一段逻辑必须分环境执行,Nuxt 提供了超简单的全局变量:

if (import.meta.server) {
  console.log('这段代码只在服务器跑,比如读文件、查数据库')
}

if (import.meta.client) {
  console.log('这段代码只在浏览器跑,比如 window.alert()')
}

需要注意

虽然同构渲染很强大,但因为它“一份代码两处运行”,开发者需要注意:

  • **Window/Document 对象:**在setup()created()生命周期中,代码会在服务端运行。此时没有浏览器环境,直接访问windowlocalStorage会报错。你需要通过process.client判断或在onMounted 中执行。
  • 状态同步: 服务器获取的数据必须“脱水”传给客户端,客户端再“注水”还原,否则会导致客户端渲染结果与服务端不一致(Hydration Mismatch)。
  • 服务器压力: 相比于纯静态文件分发,服务器需要运行 Node.js 环境来渲染页面,对 CPU 有一定消耗。

水合现象 (Hydration)

水合(Hydration) 是一个非常形象的比喻。

服务器返回的是“干”的 HTML(纯文本,没有交互逻辑,就像脱水的蔬菜)。浏览器下载了 Vue 的 JavaScript 束后,Vue 会在后台运行,将这些 JS 逻辑挂载到现有的 HTML 结构上,让页面变得“湿润”起来(可点击、有动画、响应式)。

水合的过程:

  1. 下载 JS:浏览器显示 HTML 后,开始下载框架代码。
  2. 激活阶段:Vue 在客户端扫描服务器传来的 DOM 结构。
  3. 对比与挂载:Vue 创建虚拟 DOM,并尝试将其与现有的真实 DOM 匹配。如果匹配成功,Vue 接管 DOM,绑定事件监听器。

Nuxt 生命周期钩子

在 Vue 3 的基础上,Nuxt 的生命周期主要关注“什么时候能访问浏览器特有对象”。

  • setup()** 期间**:服务端和客户端都会执行。绝对不能在这里访问windowdocumentlocalStorage
  • onMounted()仅在客户端执行。如果你要操作 DOM、初始化地图 SDK、或者读取 Cookie/Token,请务必放在这里。

什么时候是 SSR?什么时候是 CSR?

这是很多初学者最容易困惑的地方。简单来说:“首次进入是 SSR,后续跳转是 CSR。”

  1. 情况 A:服务端渲染 (SSR)
  • 动作: 你在浏览器地址栏输入网址敲回车,或者手动刷新页面。
  • 过程: 请求发送到 Node.js 服务器,Nuxt 执行所有初始化和数据获取钩子,生成 HTML 返回。
  • 表现: 右键查看源代码,可以看到完整的页面文字内容。
  1. 情况 B:客户端渲染 (CSR)
  • **动作:**页面加载完成后,你点击了<NuxtLink> 进行站内跳转。
  • 过程: 浏览器不会重新请求服务器拿 HTML,而是通过 JS 拦截路由,直接在浏览器里下载新页面的数据并渲染组件。
  • 表现: 体验像单页应用(SPA),没有白屏,速度极快。