文章目录
2 组件的生命周期
组件生命周期指的是组件从创建到销毁的过程,在这个过程中的一些不同的阶段,vue
会调用指定的一些组件方法。
基本生命周期函数有下面几个阶段:
- 创建阶段
- 挂载阶段
- 更新阶段
- 卸载阶段
- 其它
每一个阶段都对应着 之前
和 之后
两个函数。
2-1 创建阶段
beforeCreate()
在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。初始化阶段,应用不多。
created()
在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),property 和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el
property 目前尚不可用。
2-2 挂载阶段
beforeMount()
在挂载开始之前被调用:相关的 render
函数首次被调用。
mounted()
该阶段执行完了模板解析,以及挂载。同时组件根组件元素被赋给了 $el
属性,该阶段可以通过 DOM 操作来对组件内部元素进行处理了。
2-3 更新阶段
beforeUpdate()
数据更新时调用,但是还没有对视图进行重新渲染,这个时候,可以获取视图更新之前的状态。
updated()
由于数据的变更导致的视图重新渲染,可以通过 DOM 操作来获取视图的最新状态。
任何数据的更新都会触发这个事件
.$nextTick()
将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick
一样,不同的是回调的 this
自动绑定到调用它的实例上。
与 updated
有些类似,this.$nextTick()
可以用作局部的数据更新后DOM更新结束后的操作,全局的可以用 updated
生命周期函数。
案例
利用alert
阻断执行,来观察beforeUpdate
和updated
两种状态
<div id="app">
<my-component></my-component>
</div>
<script src="./js/vue.js"></script>
<script>
Vue.component('my-component', {
template: `<div>
MyComponent
<button @click="setA" ref="getA">{{a}}</button>
<button @click="setB" ref="getB">{{b}}</button>
<button @click="setC" ref="getC">{{c}}</button>
</div>`,
data() {
return {
a: 1,
b: 2,
c: 100
}
},
updated() {
console.log('updated函数,此时页面已经更新,更新后的数据');
console.log(this.$refs.getA.innerHTML);
console.log(this.$refs.getB.innerHTML);
console.log(this.$refs.getC.innerHTML);
},
methods: {
setA() {
// 数据变化不会立即渲染视图
this.a++;
console.log("更新前的数据", this.a, this.$refs.getA.innerHTML);
alert("setA()改变数据,但是此时并未更新页面")
},
setB() {
this.b++;
console.log("更新前的数据:", this.b, this.$refs.getB.innerHTML);
alert("setB()改变数据,但是此时并未更新页面")
},
setC() {
this.c++;
// 通过$nextTick回调函数中获取修改后的数据
this.$nextTick(() => {
alert("通过$nextTick回调函数中获取修改后的数据");
console.log("获取修改后的数据", this.$refs.getC.innerHTML);
});
}
}
});
new Vue({
el: '#app',
data: {
}
});
</script>
点击1
点击100$nextTick
2-4 卸载阶段
beforeDestroy()
实例销毁之前调用,移除一些不必要的冗余数据,比如定时器。
定时器移除
<div id="app">
<button @click="isShow = !isShow">{{isShow}}</button>
<my-component v-if="isShow"></my-component>
</div>
<script src="./js/vue.js"></script>
<script>
Vue.component('my-component', {
template: `<div>MyComponent</div>`,
created() {
setInterval(() => {
console.log(Math.random());
}, 1000);
},
beforeDestroy() {
console.log('beforeDestroy')
},
destroyed() {
console.log('destroyed')
}
});
new Vue({
el: '#app',
data: {
isShow: true
}
});
</script>
销毁了组件,但是定时器依然存在
通过设置定时器变量,在beforeDestroy阶段销毁定时器
destroyed()
Vue 实例销毁后调用。
2-5 errorCaptured()
当捕获一个来自子孙组件的错误时被调用,此钩子会收到三个参数:
- 错误对象
- 发生错误的组件实例
- 以及一个包含错误来源信息的字符串。
此钩子可以返回 false
以阻止该错误继续向上传播。
设置错误时显示联系管理员
<div id="app">
<err-container>
<kkb-component></kkb-component>
</err-container>
</div>
<script src="./js/vue.js"></script>
<script>
Vue.component('err-container', {
data() {
return {
err: false
}
},
template: `<div><slot v-if="!err"></slot><h1 v-else>请联系管理员!</h1></div>`,
errorCaptured() {
console.log('errorCaptured');
this.err = true;
}
});
Vue.component('kkb-component', {
data() {
return {
a: 1
}
},
// 调用一个不存在的属性
template: `<div>组件{{a.b.c}}</div>`,
});
new Vue({
el: '#app',
data: {
}
});
</script>
2-6 生命周期的一些使用场景
created 进行ajax请求异步数据的获取、初始化数据
mounted 挂载元素dom节点的获取
$nextTick 针对单一事件更新数据后立即操作dom
updated 任何数据的更新