Vue的生命周期可以说是最基本的知识之一也是老生常谈的话题了,虽然很基础但是面试和平时使用中总是少不了它,这里我想根据我自己平时学习和工作中对Vue生命周期的理解和应用来做一个总结。
先附上一张官方文档的图:
生命周期钩子
-
beforeCreate()- 状态:this已经指向了实例,但是并不能访问实例中的诸如data、methods、computed等属性或者方法。
- 实践应用:常用于初始化非响应变量。还可以增加一些loading的动画效果然后在
created()的时候移除。
-
created()- 状态:实例创建完之后马上调用,此时已经可以访问data、methods、computed等属性或者方法,但是还未挂载到DOM上,所以还无法访问
$refs和$el。 - 实践应用:只进行简单的异步请求,因为此时视图还未完全出现,过多的网络请求会导致首屏加载过慢。
- 状态:实例创建完之后马上调用,此时已经可以访问data、methods、computed等属性或者方法,但是还未挂载到DOM上,所以还无法访问
-
beforeMount()- 状态:挂载之前被调用,
render函数会首次被调用。
- 状态:挂载之前被调用,
-
mounted()- 状态:实例已经挂载到了DOM上,此时可以获取到DOM节点,
$refs和$el属性都可以访问。需要注意的是子组件并不能保证一定被挂载,如果要确定所有子组件都挂载,需要使用vm.$nextTick() - 实践应用:获取虚拟节点(virtual node即VNode)信息和操作。可以开始进行一些初始化数据的操作。
- 状态:实例已经挂载到了DOM上,此时可以获取到DOM节点,
-
beforeUpdate()- 状态:数据更新时调用,发生在虚拟DOM打补丁之前,此时数据已经是最新的数据 但是页面还是旧的页面。
- 实践应用:在更新前访问DOM,可手动移除事件监听器。
-
updated()- 状态:DOM已经更新,可以进行DOM操作。
- 实践应用:虽然数据更新以后会调用该方法,但是不要在此函数中操作数据,处理不当会陷入死循环,比如你在此钩子中设置
this.isShow = !this.isShow。这个时候会陷入死循环。但是如果在watch方法中做同样的操作,会直接报错:You may have an infinite update loop in watcher with expression "isShow",故而此时更应该使用监听方法watch和计算属性computed进行数据更新的处理。(watch和computed的介绍在下面补充说明)
-
beforeDestroy()- 状态:实例销毁之前调用,此时实例还完全可用
- 实践应用:可做一些交互提示,比如:你确认xx吗?。也可以用于销毁定时器、移除事件监听器、解绑全局时间、销毁插件对象等,避免内存泄露。
-
destroyed()- 状态:实例销毁以后调用,对应Vue实例的所有指令都被解绑,所有事件监听器被移除,所有的子实例也被销毁。
-
activated()- 状态:
keep-alive组件激活时调用。 - 实践应用:有的时候我们对某些页面做了缓存,从别的页面返回到此页面时,需要手动触发一些接口数据来更新页面,此时就可以在此生命周期内进行。
- 状态:
-
deactivated()- 状态:
keep-alive组件停用时调用。
- 状态:
生命周期在其他场景的应用
-
在使用eventBus总线机制进行非父子页面传值时,也会涉及到生命周期的问题,详情可以看我这篇文章关于Vue eventBus总线传值时的生命周期问题
-
需要特别说明的是,如果是使用SSR(服务端渲染),有以下生命周期不会被调用:
beforeMount()mounted()beforeUpdate()update()activated()deactivated()beforeDestroy()destroy()