hello,我是小索奇,精心制作的Vue系列持续发放,涵盖大量的经验和示例,如果对您有用,可以点赞收藏哈~
生命周期
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:666 beforeCreate() { 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