Vue2里的onactivated是干啥的?咋用?
想弄明白Vue2里的onactivated到底是干啥的?咋在项目里用起来?好多刚开始学Vue的小伙伴,容易把它和普通生命周期钩子搞混,今天咱就把onactivated的作用、用法、踩坑点这些事儿,拆开来好好唠唠~
onactivated是干啥的?
首先得明确,onactivated是Vue2专为<keep-alive>
组件设计的生命周期钩子,那<keep-alive>
是干啥的?简单说,它能“缓存”组件实例,避免组件反复创建、销毁,提升性能,比如做Tab切换、多标签页这类场景,来回切的时候,组件不用重新初始化,直接从缓存里拿。
而onactivated呢,就是组件被<keep-alive>
缓存后,激活显示”时触发的钩子,举个例子:你做了个带Tab的页面,Tab1是商品列表,Tab2是订单列表,用<keep-alive>
把这俩Tab包起来,第一次点Tab1,组件初始化、渲染;切到Tab2再切回来,Tab1不会重新走created
、mounted
那套初始化流程,而是触发onactivated
——这时候就能在onactivated
里干些“激活后要做的事”,比如刷新数据、恢复滚动位置之类的。
要是组件没被<keep-alive>
包裹,onactivated根本不会触发!这点新手特容易忘,得记牢~
onactivated和created、mounted有啥区别?
很多人分不清这几个钩子的触发时机,咱用场景对比一下:
假设组件被<keep-alive>
包着,第一次进入组件时,执行顺序是:created → mounted → activated
;之后切走(比如切到别的Tab),会触发deactivated
;再切回来激活时,只有activated
会触发,created
和mounted
不会再执行了。
所以核心区别是:created
、mounted
管“组件初始化”(只执行一次),onactivated
管“组件被激活显示”(每次激活都执行),打个比方,created
像“新生儿第一次睁眼”,只发生一次;onactivated
像“睡一觉醒来睁眼”,每次醒来都触发~
哪些场景适合用onactivated?
知道了触发时机,咱得搞清楚啥时候用它才顺手,分享几个常见场景:
页面状态恢复
比如做个带表单的页面,用户填了一半切走,回来想接着填,虽然<keep-alive>
本身会缓存组件数据,但如果是依赖外部状态(比如滚动条位置、输入框焦点),就得在onactivated
里处理,举个栗子:列表页切走前滚动到第20条,切回来想自动回到第20条,就可以在onactivated
里写“把滚动位置设回去”的逻辑。
数据刷新需求
有些页面切走再回来,得拉最新数据,比如消息中心,切回来要显示最新未读消息,这时候在onactivated
里发请求,比在created
里灵活——因为created
只执行一次,而onactivated
每次激活都执行,像后台管理系统的“订单列表”标签页,切换回来时,在onactivated
里调接口拉最新订单,用户就能看到实时数据。
事件监听重新绑定
如果组件销毁时手动移除了事件监听(比如window
的resize
事件),激活时得重新绑上,举个例子:组件里有个功能,要根据窗口大小调整布局,在mounted
里绑了window.resize
事件,beforeDestroy
里解绑了,那切回来激活时,就得在onactivated
里重新绑定resize
事件,不然窗口大小变化时,布局逻辑就失效了。
用onactivated容易踩的坑是啥?
用的时候稍不注意就掉坑里,提前避坑很重要:
忘记给组件套<keep-alive>
这是最基础也最容易犯的错!要是组件没被<keep-alive>
包裹,onactivated永远没机会触发,所以写代码前,先确认场景是不是需要缓存——比如Tab切换、多标签页这类“切走还得回来”的场景,再给组件包上<keep-alive>
。
生命周期执行顺序搞混
尤其是和路由钩子(比如beforeRouteEnter
)混在一起时,很容易乱,被<keep-alive>
包着的组件,第一次进入是“路由钩子→created
→mounted
→activated
”;再次进入时是“路由钩子→activated
”,如果在这些钩子里头写了数据请求、状态修改的逻辑,得理清楚执行顺序,避免重复请求或者状态错乱。
数据缓存和更新的矛盾
<keep-alive>
会缓存组件实例,数据也跟着被缓存,这时候要注意:你是想“保留用户之前的操作(比如表单输入)”,还是“每次激活都清空重新加载”?比如做登录页,肯定不能缓存状态,这时候就不能用<keep-alive>
;但做个人信息编辑页,切走再回来想保留输入内容,那onactivated
里就别瞎清数据,得根据业务场景,在onactivated
里写对应的逻辑,别搞反了。
咋正确写onactivated的逻辑?
光说不练假把式,拿实际项目场景举个例子,比如做带缓存的新闻列表页:
先给路由视图套<keep-alive>
(一般在App.vue
或者布局组件里):
<template> <div id="app"> <keep-alive> <router-view></router-view> </keep-alive> </div> </template>
然后在新闻列表组件里写逻辑:
export default { data() { return { newsList: [] // 存储新闻数据 } }, activated() { // 每次激活时,拉取最新新闻 this.fetchNews() }, created() { // 第一次加载时,也拉取新闻(因为第一次进入会走created→mounted→activated) this.fetchNews() }, methods: { fetchNews() { // 这里用axios举例子,实际项目换自己的请求工具 axios.get('/api/getNews').then(res => { this.newsList = res.data }) } } }
解释一下:第一次进入组件,created
和activated
都会触发fetchNews
,确保数据加载;之后切走再回来,只有activated
触发,又能拉最新数据,这样不管是首次加载还是再次激活,新闻列表都是最新的~
再延伸个表单状态恢复的例子:比如用户填了昵称、手机号,切走再回来要保留输入内容,还得把输入框焦点设回去,代码大概这样:
export default { data() { return { nickname: '', phone: '' } }, activated() { // 激活时,把昵称输入框的焦点设上(假设输入框ref叫nicknameInput) this.$nextTick(() => { this.$refs.nicknameInput.focus() }) }, // 其他生命周期... }
这里用$nextTick
是因为activated
触发时,DOM可能还没完全更新,等DOM更新完再设焦点更稳~
原理层面:onactivated咋实现的?
(这部分稍微深入点,帮大家理解本质)Vue的<keep-alive>
是通过缓存VNode来实现组件实例缓存的,当组件被缓存后,再次渲染时,不会走完整的创建流程(new VueComponent
那套),而是从缓存里拿现成的VNode,这时候,Vue会触发activated
钩子,告诉我们“组件被激活显示了”;对应的,组件失活(切走)时触发deactivated
。
简单说,<keep-alive>
是“性能优化工具”,onactivated
和deactivated
是“给开发者在组件激活/失活时插逻辑的入口”,理解了这个原理,就知道啥时候该用这俩钩子,不会和其他生命周期搞混~
Vue3里的onactivated有啥变化?
虽然咱聊的是Vue2,但顺嘴提一嘴Vue3(毕竟很多项目在升级):Vue3的组合式API里,用onActivated
(注意首字母大写),写法变成 hooks 风格,
import { onActivated } from 'vue' setup() { onActivated(() => { // 激活时的逻辑 }) }
但核心作用和Vue2的onactivated
是一样的,都是在<keep-alive>
激活时触发,了解这个差异,以后看不同版本代码时就不懵啦~
onactivated是Vue2里和`
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。