一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
前言
在上一篇文章中,讲过了vue应用的基础概念,今天我们要更深入的了解一下vue了。之前的文章中,也大致用过和了解过部分生命周期函数,在今天的文章中,将会带大家了解vue所有的生命周期函数。
什么是生命周期函数?
- 在某一时刻会自动执行的函数
触发函数
在之前的代码中,我们会在元素上用v-on:click绑定一个点击事件,当我们点击元素之后就会触发方法中的逻辑。
<script>
Vue.createApp({
data(){
return {
message: 'Hello World'
}
},
methods: {
handleClick(){
alert('点击触发')
}
},
template: "<div v-on:click='handleClick'>{{message}}</div>"
}).mount('#root');
</script>
通过上面的代码可以看出,点击事件触发时,是调用的methods里面的函数,下面我们就用mounted函数来简单介绍一下这两者的区别。
<script>
Vue.createApp({
data(){
return {
message: 'Hello World'
}
},
mounted(){
alert('mounted函数')
},
methods: {
handleClick(){
alert('点击触发')
}
},
template: "<div v-on:click='handleClick'>{{message}}</div>"
}).mount('#root');
</script>
通过刷新浏览器,我们会发现页面中的元素还没加载出来的时候,就自动执行了mounted函数,而且mounted函数是和methods同级的,并不是像其他函数一样包含在methods中的。
生命周期详解
此处是生命周期详解的通用代码,下面的生命周期函数或者相关代码都会在此基础上增改。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
Vue.createApp({
data(){
return {
message: 'Hello World'
}
},
// 此处开始写生命周期函数
// 此处是模板
template: "<div>{{message}}</div>"
}).mount('#root');
</script>
</html>
首先我们看到的就是创建一个vue实例,紧接着就开始执行vue里面的逻辑了。
-
第一步:初始化vue代码,分析vue代码是否有一些事件的绑定(如:
v-on)或者是上面提到的生命周期函数(如:mounted) -
第二步:执行vue中的第一个生命周期函数
beforeCreate-
beforeCreate:在实例生成之前会自动执行的函数- 在代码模板中,写下
beforeCreate函数,打开浏览器看看执行效果
beforeCreate(){ console.log('beforeCreate函数') }, - 在代码模板中,写下
-
-
第三步:继续对vue进行初始化,开始分析代码中数据和模板的绑定相关的内容。
-
第四步:执行vue中的第二个生命周期函数
created-
created:在实例生成之后会自动执行的函数- 在执行完
beforeCreate函数之后,会紧接着执行created函数
created(){ console.log('created函数') }, - 在执行完
-
-
第五步:判断代码中是否有
template选项,有则走左侧的yes,无则走右侧的no -
第六步:为
yes的时候,vue会将template转为一个render函数,变为函数之后,会将数据和这个函数结合,才能把最终的内容渲染出来。 -
第七步:执行vue中的第三个生命周期函数
beforeMount-
beforeMount:在组件内容被渲染到页面之前自动执行的函数- 在
template转为render函数之后,就会执行beforeMount函数
beforeMount(){ console.log('beforeMount函数') }, - 在
-
-
第八步:用生命周期的函数对数据进行一个结合,生成我们最终想要的一个新的DOM,然后用新的DOM去替换掉
body中和vue实例相匹配的DOM(在之前的代码中,是替换掉id=root的div标签),最终页面上展示的就是vue实例想要创建出的内容了。 -
第九步:当页面挂载完成之后,会执行vue中的第三个生命周期函数
mounted-
mounted:在组件内容被渲染到页面之后自动执行的函数- 在
beforeMount执行完成之后,就表示页面已经被渲染出来了,此时就会执行mounted函数
mounted(){ console.log('mounted函数') }, - 在
-
beforeMount和mounted对比
代码运行成功之后,只能看到浏览器上打印出来的顺序,但是不知道页面渲染的情况,那么下面我们就一起来对beforeMount和mounted两个函数做一个对比。
<body>
<div id="root"></div>
</body>
- 在
body里面,是有一个id = root的标签元素
Vue.createApp({
data(){
return {
message: 'Hello World'
}
},
beforeCreate(){
console.log('beforeCreate函数')
},
created(){
console.log('created函数')
},
beforeMount(){
console.log(document.getElementById('root').innerHTML, 'beforeMount函数')
},
mounted(){
console.log(document.getElementById('root').innerHTML, 'mounted函数')
},
template: "<div>{{message}}</div>"
}).mount('#root');
- 在
beforeMount和mounted两个函数里面,我们打印一下root下面的innerHTML内容
- 通过打印出来的内容可以看出,页面加载完成之后,但是模板还没生成
render函数时,beforeMount函数前面是没有打印出任何数据的。在页面渲染完成之后,mounted函数就会打印出root标签下渲染的内容了。
做完上面九个步骤之后,一个完整的vue页面就被渲染出来了,但是我们看到图中还有其他的四个生命周期函数,这四个生命周期函数并不是主动触发的,而是当你有操作之后才会触发的,下面我们就详细讲解一下这四个生命周期函数吧。
-
beforeUpdate:当data中的数据发生变化时自动执行的函数- 首先我们把代码里面的逻辑改造一下,为了后面方便触发函数,并在代码中写上了
beforeUpdate函数
const app = Vue.createApp({ data(){ return { message: 'Hello World' } }, beforeCreate(){ console.log('beforeCreate函数') }, created(){ console.log('created函数') }, beforeMount(){ console.log('beforeMount函数') }, mounted(){ console.log('mounted函数') }, beforeUpdate(){ console.log('beforeUpdate函数') }, template: "<div>{{message}}</div>" }); const vm = app.mount('#root'); - 首先我们把代码里面的逻辑改造一下,为了后面方便触发函数,并在代码中写上了
但是在浏览器中,并没有看到beforeUpdate被执行,这时候我们应该怎么触发效果呢?
在下图中,我们可以看到用vm.$data改变data里面的数据时,会自动执行beforeUpdate函数,而且是在页面渲染之前触发的。
-
updated:当data中的数据发生变化,同时页面完成更新后,会自动执行的函数- 在
beforeUpdate的代码基础上,我们加上updated函数
updated(){ console.log('updated函数') }, - 在
此时打开浏览器更新的时候,发现并没有很直观的感受,那么我们就对这两个函数做一个对比看看。
beforeUpdate和updated对比
我们像上面对比beforeMount和mounted函数时一样,将root标签里面的innerHTML打印出来看看
beforeUpdate(){
console.log(document.getElementById('root').innerHTML, 'beforeUpdate函数')
},
updated(){
console.log(document.getElementById('root').innerHTML, 'updated函数')
},
根据浏览器中的输出内容可以看出,在beforeUpdate函数执行的时候,还未更新data中的数据,所以打印出来的还是之前的innerHTML内容;但是当更新完成之后,就会在updated函数中打印出新的innerHTML内容了。
把上面的生命周期函数搞懂之后,接下来就是最后两个生命周期函数了。
当vue实例创建完成之后,页面也会挂载到id=root的节点上,但是当我们不想要挂载了,想要把vue实例给销毁掉,那我们应该怎么操作呢?
- 上面生命周期的图示中已经给到答案了,就是用
app.unmount函数可以模拟操作销毁vue实例
当执行app.unmount函数之后,页面上渲染的内容也被清空了,此时也就表示vue实例被销毁了。
beforeUnmount:当vue应用失效时,自动执行的函数unmounted:当vue应用失效时,且DOM完全销毁之后,自动执行的函数
beforeUnmount(){
console.log('beforeUnmount函数')
},
unmounted(){
console.log('unmounted函数')
},
beforeUnmount和unmounted对比
同样,我们可以在这两个函数里面打印innerHTML来看看最终的效果
beforeUnmount(){
console.log(document.getElementById('root').innerHTML, 'beforeUnmount函数')
},
unmounted(){
console.log(document.getElementById('root').innerHTML, 'unmounted函数')
},
在页面销毁之前,也就是beforeUnmount函数执行时,页面的内容还是不变的;当页面彻底销毁之后,unmounted函数打印出来的内容就没有vue实例里面的任何节点内容了。
总结
在本节内容中,我们主要学习了vue所有的生命周期函数:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeUnmount、unmounted
但是生命周期这么多,该如何使用呢?在后面的文章中,会用各种案例带着大家对生命周期的使用有更多的了解。