Vue.js 组件生命周期
生命周期函数(钩子)就是给我们提供了一些特定的时刻,让我们可以在这个周期段内加入自己的代码,做一些需要的事情;
生命周期钩子中的this指向是VM 或 组件实例对象
在JS 中,函数的执行上下文(也就是函数内部的
this
指向的对象)取决于函数的调用方式而 Vue 在创建组件实例时,会在内部确保生命周期钩子函数的执行上下文是指向组件实例的具体来说,当 Vue 创建一个组件实例时,它会使用JS 的
Function.prototype.bind
方法来绑定组件实例作为函数内部的this
这意味着无论在哪个生命周期钩子函数中,我们使用的this
都会指向当前组件实例
-
初始化:
-
Events & Lifecycle:初始化生命周期、事件,数据代理尚未开始(beforeCreate前)
-
Injections & reactivity:初始化数据监测、数据代理,(beforeCreate实例创建后)
-
-
创建阶段:
-
beforeCreate: 在数据监测、数据代理注入之前,在这个阶段初始化生命周期、事件,但数据代理还未开始注入
数据代理:Vue 会将组件实例上的数据(data)、计算属性(computed)、方法(methods)等代理到实例本身上,在
beforeCreate
阶段使得我们可以通过this
访问到vm,我们不能通过this
直接访问data
中的数据和methods
中的方法数据监测:Vue 开始进行数据的响应式监测,即开始追踪数据的变化以便在数据变化时更新视图。
-
created: 数据监测、数据代理都已完成,数据监测确保了数据的变化能够被 Vue 追踪和响应。此时,我们可以在组件内部通过
this
访问并操作已经初始化的 data 和 methods,但组件尚未挂载到 DOM
-
-
挂载阶段:
-
beforeMount: 组件挂载前调用,这时候操作不了真实DOM
-
mounted: 组件挂载到 DOM 后,此时页面呈现的是经过编译的真实DOM,可以进行 DOM 操作和初始化,但是尽量不要更改,刚挂载完成就给人家更改了?一般在此阶段开启定时器、发送网络清求、订阅消息、绑定自定义事件等初始化操作
-
-
更新阶段:
-
beforeUpdate: 数据更新前调用,可做准备工作
-
updated: 数据更新完成,DOM 重新渲染避免修改数据以防止循环
-
-
销毁阶段:
-
beforeDestroy: 在组件即将销毁(卸载)之前触发。这是一个很好的时机来进行一些清理工作,例如取消订阅、清除定时器、解绑事件监听器等。在这个阶段,组件仍然处于活动状态,可以访问组件的数据和方法。一旦
beforeDestroy
钩子执行完毕,组件就会被销毁,无法再通过实例访问组件的属性或方法。 -
destroyed:
destroyed
生命周期钩子在组件已经销毁(卸载)之后触发。在这个阶段,组件实例以及其所有相关的 DOM 已经被完全销毁。我们可以在这个钩子中做一些清理工作,例如释放组件占用的资源、解绑全局事件监听器等。与beforeDestroy
不同,此时无法访问组件的数据和方法,因为组件实例已经被销毁在destoryed这个阶段一般什么都不做,在react中没有这个阶段
-
-
其他钩子:
-
activated(仅用于 keep-alive 组件):组件激活时调用
-
deactivated(仅用于 keep-alive 组件):组件停用时调用
-
errorCaptured: 捕获组件内部错误,类似于 try-catch
-
下面具体说明一下细节
测试时候记得配合debugger
开控制台刷新使用,否则一下子执行完生命周期了:
// data中定义了number:666beforeCreate() {console.log('实例创建前')console.log(this)debugger}
Vue实例中number为undefined
下图中template和Outer 指的是哪?
-
OuterHTML:指的就是外面绿色框框内的,
div
都会作为模板进行解析 -
InnerHTML:在内部的也就是
InnerHTML
-
不进行
outer
的初始化操作可能会导致我们无法获得正确的outerHTML
值,这个没多大影响
编译模板到渲染函数内:当我们把上述整个div
清除时,就会尝试编译template
作为模板进行解析,template
将其完全替代渲染到页面上
在created
之后,beforeMounted
之前,这一个阶段Vue开始解析模板,在内存中生成虚拟DOM,页面已经解析完了,但是还没有显示到页面上
-
在
beforeMount
此时呈现的是未经编译的DOM结构,是不能够操作真实DOM的,所有对DOM的操作最终都不生效,控制台更改瞬时生效,执行完$el 替换之后,还是把虚拟DOM拿过来瞬间生成真实DOM插入页面(虚拟DOM是在created
之后,beforeMount
之前生成的虚拟DOM,所以在beforeMount
这时怎么修改也只是瞬间生效)
设上端点,在页面上操作进行DOM,可以发现页面的确显示了(没有断点,根本不会看到任何变化)
一旦点击下一步页面立即回复原样,说明了此时不能操作DOM
-
在
Created VM.$el and replace "el" with it
这里用$el
替换整个el容器的东西,这一步内存中的虚拟DOM转换成真实DOM,并且在VM.$el上进行存储 -
mounted
此时页面呈现的是经过编译的真实DOM,可以进行 DOM 操作和初始化,但是尽量不要更改,刚挂载完成就给人家更改了?一般在此阶段开启定时器、发送网络清求、订阅消息、绑定自定义事件等初始化操作
页面和数据尚未保持同步的是哪一个阶段?
是在
beforeUpdate
这个阶段,此时数据是新的,页面时旧的
这里定义了number="666",可以看到控制台已经更新了667,页面尚未刷新
之后就不断根据新数据生成新DOM,并与旧DOM对比,最终完成页面更新;
即 Model->View 数据绑定的更新
在每次数据变化触发更新时,Vue 会创建一个新的虚拟 DOM,然后将新的虚拟 DOM 与之前的虚拟 DOM 进行比较,找出差异,然后将这些差异应用于真实 DOM.