每个vue实例从创建到销毁的过程就是vue的一个生命周期,每个阶段都有对应的钩子函数,当我们想在vue的不同时期操作vue实例是,就可以在不同的钩子函数中进行
vue有8种生命周期函数:
beforeCreate(实例创建前)
这个时候this还不能使用,data中的数据、methods中的方法,以及watcher中的事件都不能获得。
var vm = new Vue({el: '#app',data: {message: '今天是周一!!!'},beforeCreate(){console.group('beforeCreate 创建前状态==========>>');console.log("%c%s", "color:red", "el: "+this.$el); //undefinedconsole.log("%c%s", "color:red", "data : "+this.$data); //undefinedconsole.log("%c%s", "color:red", "message: "+this.message); //undefined},
created(实例创建后)
这个时候可以操作vue中的数据和方法,但是还不能对dom节点进行操作。
//...created(){console.group('created 创建完毕状态==========>>');console.log("%c%s", "color:red", "el: "+this.$el); //undefinedconsole.log("%c%s", "color:red", "data : "+this.$data); //[object Object]console.log("%c%s", "color:red", "message: "+this.message); //今天是周一!!!},//...
beforeMoute(元素挂载前)
$el属性已存在,是虚拟dom,只是数据未挂载到模板中。
//...beforeMount(){console.group('beforeMount 挂载前状态==========>>');console.log("%c%s", "color:red", "el: "+this.$el); //[object HTMLDivElement]console.log(this.$el);console.log("%c%s", "color:red", "data : "+this.$data); //[object Object]console.log("%c%s", "color:red", "message: "+this.message); //今天是周一!!!},//...
mouted(元素挂载后)
数据和dom都完成挂载,在上一个周期占位的数据把值渲染进去,一般请求会放在这个地方,因为这边请求改变数据之后刚好能渲染注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick替换掉 mounted
//...mounted(){console.group('mounted 挂载结束状态==========>>');console.log("%c%s", "color:red", "el: "+this.$el); //[object HTMLDivElement]console.log(this.$el); console.log("%c%s", "color:red", "data : "+this.$data); //[object Object]console.log("%c%s", "color:red", "message: "+this.message); //今天是周一!!!},//...
beforeUpdate(实例更新前)
点击页面中的元素执行相应的事件,并触发beforeUpdate和updated钩子函数 只要是页面数据改变了都会触发,数据更新之前,页面数据还是原来的数据,当你请求赋值一个数据的时候就会执行这个周期,如果没有数据改变不执行。
//...beforeUpdate(){console.group('beforeUpdate 更新前状态==========>>');console.log("%c%s", "color:red", "el: "+this.$el); //[object HTMLDivElement]console.log(this.$el);console.log(this.$el.innerHTML); //<p>今天是周一!!!</p>console.log("%c%s", "color:red", "data : "+this.$data); //[object Object]console.log("%c%s", "color:red", "message: "+this.message); //今天周二了!!!},//...
updated(实例更新后)
只要是页面数据改变了都会触发,数据更新完毕,页面的数据是更新完成的,beforeUpdated和updated要谨慎使用,因为页面更新数据的时候都会触发,在这里操作数据很影响性能和死循环。注意 updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick替换掉 updated:
//...updated(){console.group('updated 更新完成状态==========>>');console.log("%c%s", "color:red", "el: "+this.$el); //[object HTMLDivElement]console.log(this.$el);console.log(this.$el.innerHTML); //<p>今天周二了!!!</p>console.log("%c%s", "color:red", "data : "+this.$data); //[object Object]console.log("%c%s", "color:red", "message: "+this.message); //今天周二了!!!},//...
beforeDestory(实例销毁前)
实例销毁之前调用,在这一步,实例仍然完全可用。注意:细心的小伙伴会发现beforeUpdate和updated钩子函数中的e l 一 样 , 根 据 官 方 理 解 beforeUpdate应该指向虚拟dom , 所以才会一样 , 而dom中的真正内容不一样 ,但是beforeMount和mouted钩 子函数中为什么又会有区别呢 ?感觉是设计的不足之处。执行vm.destroy()函数触发beforeDestroy和destoryed钩子函数
//...beforeDestroy(){console.group('beforeDestroy 销毁前状态==========>>');console.log("%c%s", "color:red", "el: "+this.$el); //[object HTMLDivElement]console.log(this.$el);console.log("%c%s", "color:red", "data : "+this.$data); //[object Object]console.log("%c%s", "color:red", "message: "+this.message); //今天周二了!!!},//...
destory(实例销毁后)
vue实例销毁后调用,调用后,Vue实例指示的所有内容都会解除绑定,所有的事件监听器都会被移除,所有的子实例也会被销毁。执行destroy方法后,对data的改变不会再触发周期函数,此时的vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在。
//...destroyed(){console.group('destroyed 销毁完成状态==========>>');console.log("%c%s", "color:red", "el: "+this.$el); //[object HTMLDivElement]console.log(this.$el);console.log("%c%s", "color:red", "data : "+this.$data); //[object Object]console.log("%c%s", "color:red", "message: "+this.message); //今天周二了!!!},//...
总结:
beforecreate:可以在这加个loading事件created :在这结束loading,还做一些初始化,实现函数自执行mounted : 在这发起后端请求,拿回数据,配合路由钩子做一些事情beforeDestory: 你确认删除vue实例了吗?destoryed :当前实例已被销毁,解绑相关指令和事件监听器
重点:
父子组件嵌套时触发钩子函数顺序
1.组件挂载阶段
父组件beforeCreate=>>父组件created=>>父组件beforeMount=>>子组件beforeCreate=>>子组件created=>>子组件beforeMount=>>子组件mounted=>>父组件mounted 即从创建到挂载,是从外到内,再从内到外
2.组件更新阶段
父组件beforeUpdate=>>父组件updated
3.组件销毁阶段
父组件beforeDestroy=>>子组件beforeDestroy=>>子组件destroyed父组件destroyed 即销毁是从外到内,再从内到外
以下为简单粗暴的答案 直接走起:
答: 总共分为8个阶段。创建前/后,载入前/后,更新前/后,销毁前/后。
创建前/后: 在beforeCreated阶段,vue实例的挂载元素$el和数据对象 data 都为undefined,还未初始化。在 created阶段,vue实例的数据对象data有了,$el还没有。
载入前/后: 在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。
更新前/后: 当data变化时,会触发beforeUpdate和updated方法。
销毁前/后: 在destroy阶段,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在。destroyed阶段,组件销毁