Vue的生命周期
Vue实例
创建
到销毁
的过程 ,这些过程中会伴随着一些函数的自调用,我们称这些函数为钩子函数。
总览Vue生命周期的三个阶段
1.挂载(创建):初始化相关属性->beforeCreate,created,beforeMount,mounted
2.更新(运行):元素或组件的变更操作->beforeUpdate,updated
3.销毁:销毁相关属性->beforeDestroy,destroyed
-
beforeCreate(初始化界面前)
-
created(初始化界面后)
-
beforeMount(渲染dom前)
-
mounted(渲染dom后)
-
beforeUpdate(更新数据前)
-
updated(更新数据后)
-
beforeDestroy(卸载组件前)
-
destroyed(卸载组件后)
问题来了:new 出来的Vue到底干了一件什么事
也就是说先去编译tempalte,然后再挂载到el指定的DOM元素上, 在此期间他会执行一些函数,这些函数就是生命周期函数
<div id="app">
<div id="h3">{{msg}}</div>
<input type="button" value="修改msg" @click="msg='no'">
</div>
// var vm =new Vue表示开始创建一个Vue的实例对象
//1. init Events & Lifecycle表示刚初始化了一个Vue空的实例对象
//这时候这个对象身上只有默认的一些生命周期函数和默认的事件,其他的东西未创建
//也就是该执行beforeCreate了
var vm = new Vue({
el: '#app',
data: {
msg: '初始化'
},
methods: {
show() {
console.log('执行了show方法');
}
},
beforeCreate() { //1. 这是第一个生命周期函数,表示实例完全被创建出来之前,会执行它
console.log(this.msg); //undefined
//this.show(); //this.show is not a function
// 结论:在beforeCreate生命周期执行的时候,data和methods中的数据还没有被初始化
},
created() { //2.这是第二个生命周期函数
console.log(this.msg); //初始化
this.show(); //执行了show方法
//结论:在created中,data和methods都已经被初始化好了
//如果要调用methods里面的方法或者操作data中的数据,最早只能在created中操作
},
//3.根据是否有el和templete来编译模板,把vue中的指令进行执行,最终在内存中生成一个编译好的
//模板字符串,然后把这个模板字符串渲染为内存中的DOM,但是并没有把模板挂载到真正的页面上去
beforeMount() { //3.这是第三个生命周期函数,模板已经被编译,但是没有被渲染进页面
console.log(document.getElementById('h3').innerText); //{{msg}}
},
```
mounted() { //4.这是第四个生命周期函数,已经将编译好的模板挂载到页面上去了
//mounted是实例创建期间的最后一个生命周期函数,内存中的模板已经被挂载到了页面上
console.log(document.getElementById('h3').innerText); //初始化
},
```
//5.组件运行阶段的生命周期函数:beforeUpdate,updated,她两最少执行0次,代表data数据从来没有改变
beforeUpdate() { //5.这是第五个生命周期函数,界面没有更新,数据更新了
console.log(`界面上元素的内容:${document.getElementById('h3').innerText}`);
//界面上元素的内容:初始化
console.log(`data中的数据${this.msg}`); //data中的数据no
//定义按钮改变msg的值,然后beforeUpdate函数会自动执行,界面显示数据是旧的,但是数据是最新的
},
```
updated() { //6.这是第六个生命周期函数,界面更新,数据也更新
console.log(`界面上元素的内容:${document.getElementById('h3').innerText}`);
//界面上元素的内容:no
console.log(`data中的数据${this.msg}`); //data中的数据no
},
beforeDestroy(){ //7.这是第七个生命周期函数,所有数据处于可用状态
},
destroyed(){ //8.这是第八个生命周期函数,组件已经完全被销毁了,所有的数据,方法,指令通通被销毁
}
})
有人问我,异步请求该放到哪个生命周期?
created
和mounted
都可以,但是具体的还得看业务场景
-
对于作为子组件被调用的组件里,异步请求应当在
mounted
里调用,因为这个时候子组件可能需要涉及到对dom的操作; -
对于页面级组件,当我们需要使用
ssr
(服务端渲染)的时候,只有created
是可用的,所以这个时候请求数据只能用它; -
对于页面级组件, 当我们做异步操作时,涉及到要访问dom的操作,我们仍旧只能使用
mounted
; -
对于一般情况,
created
和mounted
都是可以的;
补充一点,在mounted
被调用时,vue
不保证子组件也都被挂载完毕了,所以如果希望整个视图渲染完毕再执行操作,需要使用$nexttick
,使用方法如下:
mounted: function () {
this.$nextTick(function () {
// Code...
})
}
- $nexttick`本身会接收一个回调函数,它实际上会让里面的代码延时执行,类似于setTimeout。
根据上面的结论,我们知道大多数情况下,使用created
和mounted
做异步请求没什么区别,但是对于上面提到的几种情况需要选择其中之一。我的个人习惯是:对于页面级组件,一般在created
里调用,这样做是为了与子组件里需要在mounted
里调用做一个区分,便于提醒这个知识点。