前言
在上一篇文章中,讲过了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
但是生命周期这么多,该如何使用呢?在后面的文章中,会用各种案例带着大家对生命周期的使用有更多的了解。