43、Vue2和vue3生命周期

1、什么是vue生命周期

每一个vue实例从创建到销毁的过程,就是这个vue实例的生命周期。在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。

2、vue2的生命周期

2.1、8个生命周期函数

  1. beforeCreate(创建前):数据观测和初始化事件还未开始,此时 data 的响应式追踪、event/watcher 都还没有被设置,也就是说不能访问到data、computed、watch、methods上的方法和数据。
  2. created(创建后) :实例创建完成, 可以访问到data、computed、watch、methods上的方法和数据。但是此时渲染的节点还未挂载到 DOM,所以不能访问到 $el 属性(即 el: '#app')
  3. beforeMount(挂载前):在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。此时模板编译完成 生成html,还没有挂载html到页面上,无法获取dom。未将html{{}}中的插值替换为data中的数据
  4. mounted(挂载后):在el被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象组件挂载完成,模板中的html渲染到页面中,能直接获取到dom。此过程中进行ajax交互。将html{{}}中的插值替换为data中的数据
  5. beforeUpdate(更新前):响应式数据更新时调用,此时虽然响应式数据更新了,但是对应的真实 DOM 还没有被渲染
  6. updated(更新后) :在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。此时 DOM 已经根据响应式数据的变化更新了。调用时,组件 DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
  7. beforeDestroy(销毁前):实例销毁之前调用。这一步,实例仍然完全可用this 仍能获取到实例。
  8. destroyed(销毁后):实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务端渲染期间不被调用。

注意:mouted和updated的执行,并不会等待所有子组件都被挂载完成后再执行,所以如果你希望所有视图都更新完毕后再做些什么事情,那么你最好在mouted或者updated中加一个$nextTick(),然后把要做的事情放在$netTick()中去做。

2.2、created和mounted的区别

  1. created: 在模板渲染成html前调用,即通常初始化某些属性值,此时视图中的html还没有渲染出来
  2. mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。(此时html已经渲染出来了,所以可以直接操作dom节点)

例如:

Vue.component("demo1",{
        data:function(){
            return {
                name:"",
                age:"",
                city:""
            }
        },
        template:"<ul><li id='name'>{{name}}</li><li>{{age}}</li><li>{{city}}</li></ul>",
        created:function(){
            this.name="唐浩益"
            this.age = "12"
            this.city ="杭州"
            var x = document.getElementById("name")//第一个命令台错误
            console.log(x.innerHTML);
        },
        mounted:function(){
            var x = document.getElementById("name")//第二个命令台输出的结果
            console.log(x.innerHTML);
        }
    });
    var vm = new Vue({
        el:"#example1"
    })

可以看到输出如下:

可以看到都在created赋予初始值的情况下成功渲染出来了。

但是同时看console台如下:

可以看到第一个报了错,实际是因为找不到id,getElementById(ID) 并没有找到元素,原因如下:
在created的时候,视图中的html并没有渲染出来,所以此时如果直接去操作html的dom节点,一定找不到相关的元素;
在mounted中,由于此时html已经渲染出来了,所以可以直接操作dom节点,故输出了结果“唐浩益”。

2.3、vue2生命周期的过程举例

大致过程就是这样,下面我们来通过例子来看一看

(1)例1:没有template参数

<body>
    <div id="app">
        <p>{{message}}</p>
        <button @click="changeMsg">改变</button>
    </div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'hello world'
        },
        methods: {
            changeMsg () {
                this.message = 'goodbye world'
            }
        },
        beforeCreate() {
            console.log('------初始化前------')
            console.log(this.message) //undefined
			//console.log(this.changeMsg) //undefined
            console.log(this.$el)  //undefined
        },
        created () {
            console.log('------初始化完成------')
            console.log(this.message) //hello world
			//console.log(this.changeMsg) // changeMsg方法
            console.log(this.$el)  //undefined
        },
        beforeMount () {
            console.log('------挂载前---------')
            console.log(this.message) //hello world
            console.log(this.$el) // <div id="app">...</div>
        },
        mounted () {
            console.log('------挂载完成---------')
            console.log(this.message)
            console.log(this.$el)
        },
        beforeUpdate () {
            console.log('------更新前---------')
            console.log(this.message)
            console.log(this.$el)
        },
        updated() {
            console.log('------更新后---------')
            console.log(this.message)
            console.log(this.$el)
        }
    })
</script>

我们先看看首次加载时,输出了啥。从上面我们可以看出几点,

首次,只执行了4个生命周期,beforeCreate,created, beforeMount, mounted。

  1. 第一个生命周期beforeCreate中,我们拿不到data中的数据,因为这个时候数据还未初始化;
  2. created中,我们可以拿到data中的message数据了,因为初始化已经完成;
  3. beforeMount中,我们拿到了$el(就是页面中的#app),是渲染前的;
  4. mounted中,我们也拿到了$el,是渲染后的;

(2)例2:有template参数

var vm = new Vue({
        el: '#app',
        data: {
            message: 'hello world'
        },
        template: '<div>我是模板内的{{message}}</div>',
        methods: {
            changeMsg () {
                this.message = 'goodbye world'
            }
        },
        beforeCreate() {
            console.log('------初始化前------')
            console.log(this.message)
            console.log(this.$el)
        },
        created () {
            console.log('------初始化完成------')
            console.log(this.message)
            console.log(this.$el)
        },
        beforeMount () {
            console.log('------挂载前---------')
            console.log(this.message)
            console.log(this.$el)
        },
        mounted () {
            console.log('------挂载完成---------')
            console.log(this.message)
            console.log(this.$el)
        },
        beforeUpdate () {
            console.log('------更新前---------')
            console.log(this.message)
            console.log(this.$el)
        },
        updated() {
            console.log('------更新后---------')
            console.log(this.message)
            console.log(this.$el)
        }
    })

beforeMount的时候,$el还是#app。但是在mounted时,因为我们传了个template,就变成模板的div了。所以,他直接将这个template转换成render函数啦。再渲染成真实dom后,用渲染出来的真实dom替换了原来的$el。

3、vue3生命周期

3.1 vue3的生命周期函数

(1)Vue应用程序中有4个主要事件(8个主要钩子)。

  • 创建 — 在组件创建时执行

  • 挂载  —  DOM 被挂载时执行

  • 更新  — 当响应数据被修改时执行

  • 销毁  — 在元素被销毁之前立即运行

(2)vue2和vue3生命周期对比 

  • 与vue2相比,我们需要将生命周期钩子导入到项目中,才能使用,这有助于保持项目的轻量性。如:import { onMounted } from 'vue'。
  • beforecatecreated(它们被setup方法本身所取代)
Vue2Vue3
beforeCreatesetup
createdsetup
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestoryonBeforeUnmount
destoryedonUnmounted

(3)其它的改进:

errorCaptured -> onErrorCaptured

activated -> onActivated

deactivated -> onDeactivated

新增的钩子函数:

组合式 API 还提供了以下调试钩子函数:

  • onRenderTracked
  • onRenderTriggered

(4)vue3中的生命周期函数详解:

除了beforecatecreated(它们被setup方法本身所取代),我们可以在setup方法中访问的API生命周期钩子有9个选项:

  • onBeforeMount – 在挂载开始之前被调用:相关的 render 函数首次被调用。

  • onMounted – 组件挂载时调用

  • onBeforeUpdate  – 数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

  • onUpdated  –  由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

  • onBeforeUnmount –  在卸载组件实例之前调用。在这个阶段,实例仍然是完全正常的。

  • onUnmounted – 卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。

  • onActivated  –  被 keep-alive 缓存的组件激活时调用。

  • onDeactivated – 被 keep-alive 缓存的组件停用时调用。

  • onErrorCaptured – 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

 注意:这些生命周期钩子注册函数只能在 setup() 期间同步使用。

(5)vue3生命周期使用实例

import { onMounted, onUpdated, onUnmounted } from 'vue'

const MyComponent = {
  setup() {
    onMounted(() => {
      console.log('mounted!')
    })
    onUpdated(() => {
      console.log('updated!')
    })
    onUnmounted(() => {
      console.log('unmounted!')
    })
  },
}

参考:Vue 3 生命周期完整指南

4、 销毁生命周期的销毁过程

  • vm.$destroy() 会触发 销毁前和销毁后的钩子函数,完全销毁一个实例。清理他与其它实例的连接,解绑他的全部指令和事件监听器(解绑全部的事件监听器指的是自定义的事件,例如为按钮添加的click事件)
  • $destroy 方法 - 内部销毁。内部销毁只能销毁组件,不能销毁组件的dom结构。外部销毁不仅能销毁组件,也能销毁该组件的dom结构。

beforeDestroy

  • 实例被销毁前调用,此时实例属性与方法仍可访问(如data、methods、指令等)。

destroyed

  • 完全销毁一个实例。可清理它与其它实例的连接,解绑它的全部指令及事件监听器(如:关闭定时器、取消订阅消息、解绑自定义事件clcik)。
  • 并不能清除DOM,仅仅销毁实例
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值