VUE 钩子函数超详细解析

点击上方蓝色字体关注我吧

    一起学习,一起进步,做积极的人!

前言

Vue 实例在被创建时,会经过一系列的初始化过程,初始化过程中会运行一些函数,叫做生命周期钩子函数,通过运用钩子函数,用户在可以在Vue实例初始化的不同阶段添加自己的代码,以此来实现自己想做的事情。

生命周期钩子函数图例

以下图中标红的圆角矩形均为钩子函数,除此之外,vue高级版本还新增了一些钩子函数。

钩子函数分类

  • beforeCreate

  • created

  • beforeMount

  • mounted

  • beforeUpdate

  • updated

  • beforeDestroy

  • destroyed

  • activated

  • deactivated

    新增的钩子函数

  • errorCaptured

函数名称版本说明
beforeCreate2.0+vue实例创建初始化后,数据观测 (data observer) 和event/watch事件配置之前触发
created2.0+在实例创建完成后被立即调用,此时实例已完成数据观测 (data observer),属性方法的运算,watch/event 事件回调的配置。然而,挂载阶段还没开始,$el 属性目前不可见
beforeMount2.0+实例挂载开始之前被调用, render 函数首次被调用,该钩子在服务器端渲染期间不被调用
mounted2.0+实例已挂载。mounted 不会承诺所有的子组件也都一起被挂载,如果你希望等到整个视图都渲染完毕再进行一些操作,请用 vm.$nextTickmounted: function () {this.$nextTick(function () { // Code that will run only after the entire view has been rendered })}该钩子在服务器端渲染期间不被调用
beforeUpdate2.0+数据更新时调用,发生在虚拟 DOM 打补丁之前,这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器,该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行
updated2.0+数据更改会导致虚拟 DOM 重新渲染和打补丁,在这之后会调用updated钩子。updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,请用 vm.$nextTick :updated: function () {this.$nextTick(function () { // Code that will run only after the entire view has been re-rendere})} updated钩子被调用时,组件 DOM 已经更新,你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改实例中的状态属性,如果要相应状态改变,通常最好使用计算属性或 watcher
beforeDestroy2.0+实例销毁之前调用。在这一步,实例仍然完全可用,该钩子在服务器端渲染期间不被调用
destroyed2.0+Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会接触绑定,所有的事件监听器会被移除,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用
activated2.0+当某个组件使用了keep-alive组件缓存时,该组件激活时调用activated钩子,该钩子在服务器端渲染期间不被调用
deactivated2.0+当某个组件使用了keep-alive组件缓存时,该组件停用时调用deactivated钩子,该钩子在服务器端渲染期间不被调用
errorCaptured2.5.0+当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播

钩子函数详细解析

公共代码
<div>/{/{test/}/}</div>
data() {
        return {
            test:'hello world'
        }
    },
methods:{
      hello(){
          alert('hello')
      }
    }
beforeCreate
beforeCreate() {
        console.log('beforeCreate 钩子函数被调用')
        this.hello()
        console.log("%c%s", "color:green" , "el     : " + this.$el) //undefined
        console.log("%c%s", "color:green","data   : " + this.$data) //undefined
        console.log("%c%s", "color:green","test: " + this.test) //undefined
        console.log("-----------------------");
    }

beforeCreate钩子调用时,$el$data均未被初始化,methodswatch里的方法事件均未被初始化,在这里没什么事情可做,你可以在这时候加个loading动画

created
created() {
        console.log('created 钩子函数被调用')
        console.log("%c%s", "color:green" , "el     : " + this.$el) //undefined
        console.log("%c%s", "color:green","data   : " + this.$data) //已被初始化
        console.log(this.$data) //已被初始化
        console.log("%c%s", "color:green","test: " + this.test) //已被初始化
        this.hello()
        console.log("-----------------------")


    }

 
created钩子调用时,进行挂载数据,绑定事件。$datamethodswatch此时被初始化了,可以访问data中相关属性和methodswatch的方法事件,但是$el属性仍然不可见。 
一般可以在这里做初始数据的获取,在这里更改data的数据不会触发 updated钩子。

beforeMount
beforeMount() {
        console.log('beforeMount 钩子函数被调用')
        console.log("%c%s", "color:green" , "el     : " + this.$el) //undefined
        console.log(this.$el) //undefined
        console.log("%c%s", "color:green","data   : " + this.$data) //已被初始化
        console.log(this.$data) //已被初始化
        console.log("%c%s", "color:green","test: " + this.test) //已被初始化
        console.log("-----------------------")


    }

beforeMount钩子调用时,开始找实例或者组件对应的模板,编译模板为虚拟 dom 放入到render函数中准备渲染,此时DOM还是无法操作,$el属性仍然不可见。 
一般可以在这里做初始数据的获取,在这里更改data的数据不会触发 updated钩子。

mounted
console.log('mounted 钩子函数被调用')
        console.log("%c%s", "color:green" , "el     : " + this.$el) //已被初始化
        console.log("%c%s", "color:green","data   : " + this.$data) //已被初始化
        console.log(this.$data) //已被初始化
        console.log("%c%s", "color:green","test: " + this.test) //已被初始化
        console.log("-----------------------")

 
mounted钩子调用时,开始执行render ,渲染出真实dom,$el属性可见,在这里操作真实的dom,依赖于DOM的代码请放在此处。

beforeUpdate
mounted () {
    this.test = 'goodbye world'
  },
beforeUpdate() {
        console.log('beforeUpdate钩子函数被调用')
        console.log("%c%s", "color:green" , "el     : " + this.$el) //已被初始化
        console.log(this.$el) //已被初始化
        console.log("%c%s", "color:green","data   : " + this.$data) //已被初始化
        console.log(this.$data) //已被初始化
        console.log("%c%s", "color:green","test: " + this.test) //已被初始化
        console.log("-----------------------")


  }

 
data发生变化时,在虚拟DOM更新补丁之前,beforeUpdate钩子被调用,这里适合在更新之前访问数据未被改变的 DOM。

updated
mounted () {
    this.test = 'goodbye world'
  },
updated() {
        console.log('updated钩子函数被调用')
        console.log("%c%s", "color:green" , "el     : " + this.$el) //已被初始化
        console.log(this.$el) //已被初始化
        console.log("%c%s", "color:green","data   : " + this.$data) //已被初始化
        console.log(this.$data) //已被初始化
        console.log("%c%s", "color:green","test: " + this.test) //已被初始化
        console.log("-----------------------")


  }

data更改会导致虚拟 DOM 重新渲染和打补丁,此时调用updated钩子,这里可以访问数据更新之后的DOM

beforeDestroy
updated () {
    this.$destroy()
  },
  beforeDestroy () {
    console.log('beforeDestroy钩子函数被调用')
    console.log('%c%s', 'color:green', 'el     : ' + this.$el) // undefined
    console.log('%c%s', 'color:green', 'data   : ' + this.$data) // undefined
    console.log('%c%s', 'color:green', 'test: ' + this.test) // undefined
    this.test = 'love world'
    this.hello()
    console.log('%c%s', 'color:green', 'test: ' + this.test) // undefined
    console.log('-----------------------')
  }

$destroy() 完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。触发beforeDestroy和 destroyed 的钩子。

执行$destroy()之后,在实例或组件被销毁之前,beforeDestroy钩子被调用,此时实例仍然可用,在此钩子中调用methods中的事件,仍然会执行

destroyed
updated () {
    this.$destroy()
  },
destroyed () {
    console.log('destroyed钩子函数被调用')
    console.log('%c%s', 'color:green', 'el     : ' + this.$el) // undefined
    console.log('%c%s', 'color:green', 'data   : ' + this.$data) // undefined
    console.log('%c%s', 'color:green', 'test: ' + this.test) // undefined
    this.hello()
    this.test = 'hi world'
    console.log('%c%s', 'color:green', 'test: ' + this.test) // undefined
    console.log('-----------------------')
  }

destroyed在实例被销毁之后调用,此时,实例已完全被销毁,与其他实例的连接会被清理,指令和事件均会被解绑

activated
//App.vue
<keep-alive exclude="HelloWorld">
   <router-view/>
</keep-alive>


activated () {
    console.log('activated钩子函数被调用')
}

首页HelloWorld不设置缓存,query设置缓存,当路由从HelloWorld跳转至query,缓存组件被激活,调用activated钩子

deactivated
//App.vue
<keep-alive exclude="HelloWorld">
   <router-view/>
</keep-alive>


deactivated () {
    console.log('deactivated钩子函数被调用')
}

首页HelloWorld不设置缓存,query设置缓存,当路由从query跳转至HelloWorld,缓存组件被停用,调用deactivated钩子

errorCaptured
errorCaptured (err, vm, info) {
    console.log(err)
    console.log(vm)
    console.log(info)
}

errorCaptured是组件的一个钩子函数,用于在组件级别捕获异常。当这个钩子函数返回 false 时,会阻止异常进一步向上冒泡,否则会不断向父组件传递。

缓存系列:

项目中缓存是如何使用的?为什么要用缓存?

redis 和 memcached 有什么区别?为什么 redis 单线程却能支撑高并发?

redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现?

redis 都有哪些数据类型?分别在哪些场景下使用比较合适?

如何保证 redis 的高并发和高可用?(redis 主从架构)

Redis 哨兵集群实现高可用

redis 的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的?

redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?

了解什么是 redis 的雪崩和穿透?

如何保证缓存与数据库的双写一致性?

分布式事务系列:

Spring 分布式事务实现概览

REST微服务的分布式事务实现-使用Spring Cloud的fallback模式

Spring的分布式事务实现-使用和不使用XA

REST微服务的分布式事务实现-基于消息中间件

REST微服务的分布式事务实现-分布式系统、事务以及JTA介绍

某宝布式事务架构设计

大白话聊聊分布式事务

分布式事务解决方案

消息队列系列:

为什么使用消息队列?

如何保证消息队列的高可用?

如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?

如何保证消息的可靠性传输?或者说,如何处理消息丢失的问题?

如何保证消息的顺序性?

如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?

分库分表系列:

为什么要分库分表?

如何设计才可以让系统从未分库分表动态切换到分库分表上?

如何设计可以动态扩容缩容的分库分表方案?

分库分表之后,id 主键如何处理?

感谢戳一下在看或转发

  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值