提示:下面体验的 vue version 是 ^2.5.13
一.Vue生命周期简介
官网:https://cn.vuejs.org/v2/api/#beforeCreate
Vue实例从创建到销毁的过程,就是生命周期。详细来说也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。
首先我们来看一下官网的生命周期图(我自己做了一点点注释):
Vue提供给我们的钩子为上图的红色的文字
二.钩子详解
注释:下面代码使用组件方式
1.beforeCreate
在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。
<style>
</style>
<template>
<div>
</div>
</template>
<script>
export default {
name: 'Test',
data(){
return{
message:'this is mseeage'
}
},
watch:{
message:function(){
console.log('watch:','message 变了')
}
},
methods: {
init:function(){
console.log('这是初始化方法')
}
},
//我们在beforeCreate钩子中调用Vue的data和method
beforeCreate:function(){
console.log("beforeCreate",this.message);
this.init();
}
}
</script>
我们在上面的例子中在的beforeCreate钩子中调用Vue的data和method,来看一下结果:
可以看到Vue中的data和方法都是去不到的,并且是在wath之前执行
2.created
实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。 主要应用:调用数据,调用方法,调用异步函数
<style>
</style>
<template>
<div>
<ul>
<li v-for="(item,index) in list" :key="index">{{ item }} -- {{message}}</li>
</ul>
<p ref="pnode">p1</p>
<p id="myAnchor">p1</p>
<p>p1</p>
</div>
</template>
<script>
export default {
name: 'Test',
data () {
return {
message:'this is 张炳 message!嘿嘿!',
list:['aaaaaaaa','bbbbbbb','ccccccc']
}
},
//时刻监测数据message的变化,一但那变化就会吊该函数
watch:{
//message必须和监测的data名字一样
message:function(){
console.log('watch:','message 变了')
}
},
methods: {
foo:function(){
console.log('foo : ','这是初始化方法')
}
},
//created钩子
created:function(){
//调用Vue的data
console.log("created : ",this.message);
//调用Vue方法
this.foo();
console.log(this.$refs); //是空,更别说 获取到 this.$refs.pnode了
//无法获取到个数
console.log('li数量:',document.getElementsByTagName('li').length);
console.log('p个数:',document.getElementsByTagName('p').length);
//均无法获取到dom,无法设置
document.getElementsByTagName('p')[0].innerHTML = 'hello! zhangbing'
document.getElementById('myAnchor').innerHTML="bye! zhangbing";
},
}
</script>
可以看到:created钩子可以获取Vue的data,可以调用Vue方法 , 但 挂载阶段还没开始,$el 属性目前不可见。 this.$refs为空对象,获取dom的个数,和设置dom的innerHTML均失效,出现报错。
3.beforeMount
<style>
</style>
<template>
<div>
<ul>
<li v-for="(item,index) in list" :key="index">{{ item }} -- {{message}}</li>
</ul>
<p ref="pnode">p1</p>
<p id="myAnchor">p1</p>
<p>p1</p>
</div>
</template>
<script>
export default {
name: 'Test',
data () {
return {
message:'this is 张炳 message!嘿嘿!',
list:['aaaaaaaa','bbbbbbb','ccccccc']
}
},
beforeMount: function () {
console.log('beforeMount: li数量:',document.getElementsByTagName('li').length);
console.log('beforeMount: p数量:',document.getElementsByTagName('p').length);
}
}
</script>
官方文档:在挂载开始之前被调用:相关的 render 函数首次被调用。 beforeMount挂载钩子,此时还没有生成HTML到页面中,没法获取 dom的数量。
4.mounted
<style>
</style>
<template>
<div>
<ul>
<li v-for="(item,index) in list" :key="index">{{ item }} -- {{message}}</li>
</ul>
<p ref="pnode">p1</p>
<p id="myAnchor">p1</p>
<p>p1</p>
</div>
</template>
<script>
export default {
name: 'Test',
data () {
return {
message:'this is 张炳 message!嘿嘿!',
list:['aaaaaaaa','bbbbbbb','ccccccc']
}
},
mounted: function () {
console.log('mounted: li数量:',document.getElementsByTagName('li').length);
console.log('mounted: p数量:',document.getElementsByTagName('p').length);
}
}
</script>
el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。看到可以正常获取到dom的个数了
5.beforeUpdate
<style>
</style>
<template>
<div>
<ul>
<li v-for="(item,index) in list" :key="index">{{ item }} -- {{message}}</li>
</ul>
<p ref="pnode"> p1</p>
<p id="myAnchor">p1</p>
<p>p1</p>
<input type="button" @click="changeMessage" value="更改数据">
</div>
</template>
<script>
export default {
name: 'Test',
data () {
return {
message:'this is 张炳 message!嘿嘿!',
list:['aaaaaaaa','bbbbbbb','ccccccc']
}
},
beforeUpdate: function () {
console.log('beforeUpdate 钩子执行...');
console.log('beforeUpdate:'+this.message);
},
methods:{
changeMessage(){
this.message = 'hello. 张炳,我更改数据了'+ Math.random();
}
}
}
</script>
点击按钮 3次,出现上面的图;
数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。要明确这句话:意思是数据更新后了调用这个钩子,但是在渲染虚拟dom之前!!!所以你看到的 chrome 调控台的数据也是 数据更新后的数据!
同时,你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。 当我们更改Vue的任何数据,都会触发该函数。
6.updated
<style>
</style>
<template>
<div>
<ul>
<li v-for="(item,index) in list" :key="index">{{ item }} -- {{message}}</li>
</ul>
<p ref="pnode"> p1</p>
<p id="myAnchor">p1</p>
<p>p1</p>
<input type="button" @click="changeMessage" value="更改数据">
</div>
</template>
<script>
export default {
name: 'Test',
data () {
return {
message:'this is 张炳 message!嘿嘿!',
list:['aaaaaaaa','bbbbbbb','ccccccc']
}
},
updated: function () {
console.log('updated 钩子执行...');
console.log('updated:'+this.message);
},
methods:{
changeMessage(){
this.message = 'hello. 张炳,我更改数据了'+ Math.random();
}
}
}
</script>
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环 。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。
7.beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。
8.destroyed
Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
<div id="app">
</div>
<script type="text/javascript">
//实例化Vue
var app = new Vue({
el:'#app',
data:{
message:'this is mseeage',
},
beforeDestroy: function () {
console.log('beforeDestroy 钩子执行...',this.message)
},
destroyed: function () {
console.log('destroyed 钩子执行...',this.message)
}
})
//销毁Vue实例,触发beforeDestroy和destroyed函数
app.$destroy()
</script>
本文由 前端技术精髓 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Dec 31, 2019 at 10:01 am