p>想搞懂Vue3组件咋从创建到销毁?生命周期就是关键!不管是写个能自动刷新的列表,还是做个切换时不崩的弹窗,掌握生命周期才能精准控制组件的生老病死。下面这些问题,能帮你把Vue3生命周期摸得透透的~
Vue3 里有哪些组件生命周期钩子?
Vue3 分「选项式 API」和「组合式 API」两种写法,生命周期钩子也跟着有不同用法~ 要是用选项式 API(像Vue2那样把钩子写在export default
里),能直接用 beforeCreate
、created
、beforeMount
这些(不过Vue3里 beforeDestroy
改成 beforeUnmount
,destroyed
改成 unmounted
啦),但现在更推荐组合式 API,得先导入钩子函数,onBeforeMount
、onMounted
、onBeforeUpdate
这些,用的时候在 setup
里调用就行~
简单说,常用的钩子围绕挂载、更新、卸载这三个核心阶段划分,还有 <KeepAlive>
缓存组件时专用的激活/停用时钩子,每个阶段对应不同钩子,分工特别明确~
生命周期钩子对应的阶段到底在干啥?
得一个个拆明白,不然写代码时总踩坑!
挂载阶段:组件从“创建”到“DOM上树”
onBeforeMount
(选项式是beforeMount
):组件刚创建完,DOM 还没生成呢!这时候能搞点初始化逻辑,比如给响应式数据设默认值,但别碰 DOM(因为没地方操作)。onMounted
(选项式是mounted
):最常用!组件已经把 DOM 渲染到页面上了,这时候能安心操作 DOM、发 Ajax 请求(比如加载列表数据)、初始化第三方库(像图表库、地图 SDK),举个栗子:做个轮播图组件,得等 DOM 渲染完才能初始化轮播逻辑,放onMounted
里准没错~
更新阶段:响应式数据变了,组件重新渲染
onBeforeUpdate
(选项式是beforeUpdate
):响应式数据变了,但 DOM 还没跟着更新,这时候能拿到「更新前的状态」,比如想对比数据变化前后的 DOM 差异,或者做性能埋点统计更新次数,就用这个钩子~onUpdated
(选项式是updated
):DOM 已经跟着数据变完了!这时候能做「更新后 DOM 相关的操作」,比如表单验证(数据变了后检查输入是否合法)、调整第三方库的状态(图表数据更新后重新渲染),但注意别在这改响应式数据,不然会无限循环更新~
卸载阶段:组件从页面“移除”并销毁
onBeforeUnmount
(选项式是beforeUnmount
):组件要被销毁前触发,得赶紧清理「副作用」!比如定时器、事件监听(像window.addEventListener
)、订阅的消息(EventBus),不清理的话会内存泄漏,页面越用越卡~onUnmounted
(选项式是unmounted
):组件已经被销毁,实例也没了,这时候所有关联的东西都该清理干净,比如WebSocket 连接断开、取消定时器 ID,确保组件彻底“消失”~
Keep-Alive 专用:缓存组件的激活/停用
要是组件被 <KeepAlive>
包裹(比如页面切换时缓存组件状态),还能用到 onActivated
(组件被激活时,比如从缓存里拿出来显示)和 onDeactivated
(组件被缓存起来,暂时不显示时),比如做个带缓存的多标签页,列表页切走再切回来,用 onActivated
恢复滚动位置,体验就丝滑了~
Vue3 生命周期和 Vue2 有啥不一样?
最直观的是命名和用法变了!
- 命名调整:Vue2 的
beforeDestroy
改成onBeforeUnmount
,destroyed
改成onUnmounted
,更强调“卸载”这个动作,理解起来更顺~ - 用法升级:Vue3 主推组合式 API,钩子得「导入 + 在 setup 里调用」,Vue2 写
mounted() { ... }
,Vue3 组合式得import { onMounted } from 'vue'
,setup() { onMounted(() => { ... }) }
,这种写法能把「相关逻辑扎堆写」,不像选项式得分散在不同钩子选项里,维护起来更爽~ - 钩子弱化:Vue3 里
beforeCreate
和created
这俩钩子“存在感变低”了!因为组合式 API 里,setup
执行时机就对应这俩阶段之间(组件实例创建后,DOM 挂载前),所以直接在setup
里写初始化逻辑就行,不用再单独写beforeCreate
和created
了~
实际开发中怎么合理用生命周期钩子?
得结合场景选钩子,不然代码容易出 bug 或者性能拉胯~
场景1:初始化请求数据 → 用 onMounted
比如做个商品详情页,要加载商品信息,把 axios 请求放 onMounted
里,因为这时候 DOM 渲染完了,请求回来直接渲染数据,用户不会看到“空页面闪一下”,要是放 setup
里,DOM 还没好,就算拿到数据也没法立刻渲染,体验差~
场景2:清理定时器 → 用 onBeforeUnmount
比如做个倒计时组件,mounted
里开 setInterval
,卸载前得 clearInterval
,代码大概长这样:
import { onMounted, onBeforeUnmount } from 'vue'
setup() {
let timer = null
onMounted(() => {
timer = setInterval(() => { /* 倒计时逻辑 */ }, 1000)
})
onBeforeUnmount(() => {
clearInterval(timer)
})
}
要是不清理,组件销毁后定时器还在跑,内存泄漏+逻辑错乱(比如组件都没了还在改数据)~
场景3:响应式数据更新后改 DOM → 用 onUpdated
比如做个实时搜索组件,输入框绑了响应式数据 keyword
,每次 keyword
变了要更新搜索结果的高亮样式,这时候在 onUpdated
里操作 DOM 改样式,因为这时候 DOM 已经跟着 keyword
变完了,能拿到最新的 DOM 结构~
场景4:缓存组件状态 → 用 onActivated
/ onDeactivated
比如后台管理系统的多标签页,用户切标签时组件被缓存,列表页切走前,用 onDeactivated
把滚动位置存起来;切回来时 onActivated
把滚动位置恢复,用户体验直接拉满~
场景5:避免重复请求 → 结合 onMounted
和 ref
判断
比如列表页每次进入都请求数据,但要是用 keep-alive
缓存了,onMounted
只会执行一次,这时候得判断是否是“首次加载”,或者用 onActivated
来触发请求(如果需要每次激活都请求)~
为啥要学组件生命周期?不管它行不行?
还真不行!生命周期是「控制组件节奏」的钥匙,不管它容易踩大坑~
- 内存泄漏:比如定时器、事件监听不清理,组件都销毁了还在占用内存,页面越用越卡,用户骂骂咧咧~
- 数据不同步:比如在 DOM 没渲染时操作 DOM,拿到的是旧结构,数据改了页面却没反应,用户看到的和实际数据对不上~
- 逻辑冲突:父子组件协作时,父组件要等子组件挂载完再传数据,要是没生命周期控制,子组件还没准备好就接收数据,直接报错~
- 性能拉胯:更新阶段乱改数据,触发无限更新循环;或者该销毁的东西没销毁,白白消耗性能~
举个反面教材:有人把定时器写在 setup
里,没在卸载时清理,组件删了定时器还在跑,控制台疯狂报错不说,页面越来越卡,这就是没管生命周期的后果~
反过来,用好生命周期能让代码“丝滑又健壮”:组件该加载时加载,该更新时更新,该销毁时彻底清理,用户体验和性能都能拉满~
现在再看Vue3组件生命周期,是不是从“懵圈”到“清晰”了?记住每个钩子的阶段、用法和坑点,写组件时就像开了上帝视角,啥时候请求、啥时候清理、啥时候操作DOM,心里门儿清~下次写代码,别再把请求乱塞,定时器忘清理啦~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。