vue2vue3生命周期详解

Vue2生命周期,Vue3的生命周期

​ 相信大伙学习前端,vue这个框架是大多无法逃避的一个必学点,看了很多也只是理解了vue的几个生命周期是什么意思,但它们具体做了什么或者说起什么样的作用并没有体会到,在这一点上就如vue官网上说的一样,

你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。

正如官方文档说的,vue的生命周期会随着你学习的深入越来越清楚。

什么是生命周期

​ 用官方的话来说就是每一个vue实例从创建到销毁的过程。这个过程,vue经历了创建—初始化数据—编译模板—挂载dom—渲染、更新、渲染、卸载等一系列操作。

先来看看官方给出的一张图[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传请添加图片描述

相信这就是"万恶之源"的开始,让我们来仔细看看这到底是个什么意思

new Vue()

跟字面意思一样,创建一个vue实例,也是每一个vue实例的开始,然后初始化事件(int Events)和初始化生命周期(init Lifecycle)和初始化渲染(init RenderinitRender)

*以下内容对于初学者而言混个眼熟就行

而仅仅是初始化了这三个函数吗,其实也不然,在new vue时,内部会执行一个this._init()方法,这个方法是定义在initMixin中的。vue会去判断当前组件是否存在父组件,如果存在,就会循环的去找第一个非父组件,并将vm push进去作为子元素,定义$parent、$root、$children、$refs属性及其他属性。

beforeCreate

在这个阶段,此阶段还没有开启vue的观察者模式(即vue的双向数据绑定)等等一系列机制,简单点来说就是此阶段的data、methods、props还未被创建好,无法使用。并且会开始初始化init injections(注射)和init reactivity(反应)

ps:在beforecreate这个阶段前会执行一个mergeOptions 函数,得到$options 并且把这个设置成vue实例的属性,这个的作用就是检查我们组件的命名是否合法,是否规范

init injections此方法初始化在data/props之前被调用,作用是初始化vue的inject,也就是以后的传值用的

create

这个时候vue的data、method已经被初始化,属性也被绑定,但此时还是虚拟dom ,真实dom并没有生成,$el也不能用,这个时候可以调用data和method的数据和方法。此阶段可以获取异步ajax数据

ps:虚拟dom:简单的来说就是一个js对象,用来描述视图的界面结构,每个组件都有一个render函数,每个render函数返回一个虚拟dom树,这个后续会专门写一篇

create—>beforeMount

请添加图片描述

就如我们上面说的,el在created阶段还是undefined,但数据已经和data的属性进行了绑定。

也就是说会先判断vue实例中有没有el选项,如果没有就停止,知道实例上调用vm.$mount(el) (挂载el),

有的话就进入到判断template模板,如果有template,就把模板编译当成render函数,如果没有就把html当做模板编译,template优先级大于html模板(ps:这里又涉及到vue渲染优先级的问题,简单来说就是render函数>template>html模板,感兴趣的可以查下template)

beforeMount

此时模板已经编译完成,也就是说我们的虚拟dom已经创建完了,但并没有变成真实dom,也就是说并没有真实渲染到页面上,此时el存在,在此阶段更改数据不会触发其他的钩子函数,一般的初始化数据在这里获取

Mount

此时模板已经被渲染成真实dom,vue实例中的data里的message挂载到bom节点中去,用户可以看见渲染完成的页面,页面的数据也是通过双向数据绑定显示data中,当mount执行完,也就意味着我们这个vue实例已经完全的创建好了

beforeUpdata

从mount开始,vue实例有两种走向,一种的是beforeUpdata和destroyed,这里先说beforeUpdata。

更新前状态(view层数据变化前,而不是data数据改变前),重新渲染之前触发,也就是在这个阶段出现了vue非常经典的一个算法diff算法

ps:diff算法,这个比较复杂,感兴趣的可以查查,简单来说就是进行虚拟节点对比,返回一个patch对象,用来存放两个节点的不同地方,最后用patch记录的消息去局部更新dom,节省很多性能

updated

数据已经更新完成,dom也重新render完成

beforeDestroy

销毁前执行($destroy方法被调用的时候就会执行),一般在这里善后:清除计时器、清除非指令绑定的事件等等…)

destroyed

销毁后 (Dom元素存在,只是不再受vue控制),卸载watcher,事件监听,子组件

Vue3的生命周期

请添加图片描述

跟vue2相比其实相差不大,区别对比

Vue2生命周期 Vue3生命周期
beforeCreate setup()
created setup()
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeDestroy onBeforeUnmount
destroyed onUnmounted

vue3在vue2的基础上新增了一个setup方法,

setup 函数是 Vue3 中新增的一个生命周期函数:

setup 函数会在 beforeCreate 之前调用,因为此时组件的 data 和 methods 还没有初始化,因此在 setup 中是不能使用 this 的
所以 Vue 为了避免我们错误的使用,它直接将 setup 函数中的 this 修改成了undefined
setup函数,只能是同步的不能是异步的

父子组件之前传值的生命周期

加载渲染阶段:父beforeCreate->父Create->父beforeMounte-> 

    子beforeCreate->子Create->子ceforeMounte

    挂载:子Mounte->父Mounte

    更新:

    1.父更新子不更新:父beforeUpdata->父updata

    2.子更新父不更新:子beforupdata->子updata

    3.父子一起更新:父beforeupdata->子beforeupdata->子updata->父updata

    销毁:

    父beforeDestroy->子beforeDestroy->子Destroy->父Destroy

代码演示

这里放一个非常的简单的vue实例来帮大家理解生命周期的全过程

<!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>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="app"></div>
    <script>
        new Vue({
      
      
            data(){
      
      
                return{
      
      
                    arr:[]
                }
            },
            //一、创建阶段
            // 钩子函数,此阶段还没有开启vue的观察者模式(即双向数据绑定)等等一系列机制
            // 不能获取dom
            beforeCreate() {
      
      
                console.log('我是创建前的钩子函数')
            },
            // vue实例创建完成  这个阶段可以做一些准备性的工作  获取异步的数据 ajax
            //dom未生成
            create(){
      
      
                console.log('这个阶段,vue的实例已经创建完毕,初始化数据,但是数据并没有显示到页面上 所以不能获取到dom')
                this.flage=true;
                this.arr=[
                    {
      
      id:1,name:'zhangsan'}
                ]
            },
            // 二、挂载阶段
            // 挂载前 将template模板 编译成浏览器可读的模式
            beforMount(){
      
      
                console.log('编译阶段,没有挂载上去,不能获取dom')
            },
            mouted(){
      
      
                console.log('挂载完成,可以获取dom')
                document.addEventListener('click',function(){
      
      

                })
            },
            // 三、更新阶段
            beforeUpdate() {
      
      
                console.log('数据更新前')
            },
            update() {
      
      
                console.log('数据更新完毕')
            },
            // 四、销毁阶段

            beforeDestroy() {
      
      
                document.removeEventListener('click')
                console.log('准备销毁')
            },
            destory(){
      
      
                console.log('已经销毁')
            },
        })
    </script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/qq_51649346/article/details/126977258