18.5.1 组件的生命周期
服务端不挂载、不更新、不卸载,因此大部分生命周期钩子在服务端不会执行;误把副作用写在
created里就会造成服务端内存泄漏。
一、哪些钩子在服务端执行
| 钩子 | 服务端是否执行 | 原因 |
|---|---|---|
beforeCreate / created | ✅ 执行 | 组件初始化流程与客户端一致 |
beforeMount / mounted | ❌ 不执行 | 服务端不会把虚拟 DOM 渲染为真实 DOM,没有真正的挂载动作 |
beforeUpdate / updated | ❌ 不执行 | 服务端渲染的是应用的快照,不存在数据变化后的重新渲染 |
beforeUnmount / unmounted | ❌ 不执行 | 服务端渲染期间不会发生组件被卸载的情况 |
结论:服务端只有
beforeCreate与created会执行,其余钩子都只在客户端生效。
二、易错点:在 created 里创建定时器
export default {
created() {
this.timer = setInterval(() => {
// 做一些事情
}, 1000)
},
beforeUnmount() {
// 清除定时器
clearInterval(this.timer)
}
}
这段代码在客户端运行没有问题;在服务端运行则会内存泄漏——因为
beforeUnmount不会在服务端执行,定时器永远不会被清除。
两个解决方案
- 把创建定时器的代码移到
mounted钩子中,即只在客户端创建; - 用环境变量包住这段代码,让它在服务端不运行。经 webpack / Vite 等构建工具搭建的同构项目通常都提供该变量,例如 Vite 注入的全局变量
import.meta.env.SSR。
// 仅非 SSR 环境(客户端)执行
if (!import.meta.env.SSR) {
this.timer = setInterval(() => {
// ...
}, 1000)
}
相关
- 18.5.2 使用跨平台的 API:同构代码要避开平台特有的 API