初探 Vue 生命周期和钩子函数

栏目: JavaScript · 发布时间: 5年前

内容简介:简单来说就是好像把人的出生到死亡分成一个个阶段,你取名字肯定是在你出生阶段,而不是在成年阶段;你结婚肯定是在成年阶段,而不是在出生阶段;如果说你在出生阶段想去阶段,那肯定是不行的。组件也是一样,在钩子函数和回调函数有什么区别吗?

生命周期

生命周期函数就是 Vue 实例在某一个时间点会自动执行的函数。

简单来说就是好像把人的出生到死亡分成一个个阶段,你取名字肯定是在你出生阶段,而不是在成年阶段;你结婚肯定是在成年阶段,而不是在出生阶段;如果说你在出生阶段想去阶段,那肯定是不行的。

组件也是一样,在 实例化的时特定阶段调用特定方法,调用的这个方法就是钩子函数。

钩子函数

钩子函数和回调函数有什么区别吗?

它们区别是:

js 派函数监听事件 => 监听函数就是所谓的钩子函数 => 函数钩取事件:函数主动找事件 => 钩子函数

js 预留函数给 dom 事件, dom 事件调用 js 预留的函数 => 事件派发给函数:事件调用函数 => 回调函数

打个比方:

回调函数:可以看做是在一片地区埋了许许多多的地雷,一旦踩中了某个地雷(触发事件),地雷就会爆炸(执行函数事件)。

可以简单的理解为:

回调函数是主动事件,执行函数体内容

生命周期探究

初探 Vue 生命周期和钩子函数

<template>
    <div>{{msg}}</div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'hello world',
      msg1: ''
    }
  },
  beforeCreate () {
    console.groupCollapsed('beforeCreate 创建前状态')
    console.log('%c%s', 'color:MediumVioletRed', 'el     : ' + this.$el)
    console.log(this.$el)
    console.log('%c%s', 'color:MediumVioletRed', 'data   : ' + this.$data)
    console.log(this.$data)
    console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
    console.groupEnd()
  },
  created () {
    console.groupCollapsed('created 创建前状态')
    console.log('%c%s', 'color:MediumVioletRed', 'el     : ' + this.$el)
    console.log(this.$el)
    console.log('%c%s', 'color:MediumVioletRed', 'data   : ' + this.$data)
    console.log(this.$data.msg)
    console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
    console.groupEnd()
  },
  beforeMount () {
    console.groupCollapsed('beforeMount 挂载前状态')
    console.log('%c%s', 'color:MediumVioletRed', 'el     : ' + this.$el)
    console.log(this.$el)
    console.log('%c%s', 'color:MediumVioletRed', 'data   : ' + this.$data)
    console.log(this.$data.msg)
    console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
    console.groupEnd()
  },
  mounted () {
    console.groupCollapsed('mounted 挂载后状态')
    console.log('%c%s', 'color:MediumVioletRed', 'el     : ' + this.$el)
    console.log(this.$el)
    console.log('%c%s', 'color:MediumVioletRed', 'data   : ' + this.$data)
    console.log(this.$data.msg)
    console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
    console.groupEnd()
    setTimeout(() => {
      this.$data.msg = '123'
    }, 5000)
  },
  activated () {
    console.groupCollapsed('activated 挂载后状态')
    console.log('%c%s', 'color:MediumVioletRed', 'el     : ' + this.$el)
    console.log(this.$el)
    console.log('%c%s', 'color:MediumVioletRed', 'data   : ' + this.$data)
    console.log(this.$data.msg)
    console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
    console.groupEnd()
    setTimeout(() => {
      this.$data.msg = 'hello tiantian'
    }, 10000)
  },
  beforeUpdate () {
    console.groupCollapsed('beforeUpdate 更新前状态')
    console.log('%c%s', 'color:MediumVioletRed', 'el     : ' + this.$el)
    console.log(this.$el)
    console.log('%c%s', 'color:MediumVioletRed', 'data   : ' + this.$data)
    console.log(document.getElementById('app').innerHTML)
    console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
    console.groupEnd()
  },
  updated () {
    console.groupCollapsed('updated 更新后状态')
    console.log('%c%s', 'color:MediumVioletRed', 'el     : ' + this.$el)
    console.log(this.$el)
    console.log('%c%s', 'color:MediumVioletRed', 'data   : ' + this.$data)
    console.log(document.getElementById('app').innerHTML)
    console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
    console.groupEnd()
    setTimeout(() => {
      this.$destroy()
    }, 5000)
  },
  beforeDestroy () {
    console.groupCollapsed('beforeDestroy 实例销毁前状态')
    console.log('%c%s', 'color:MediumVioletRed', 'el     : ' + this.$el)
    console.log(this.$el)
    console.log('%c%s', 'color:MediumVioletRed', 'data   : ' + this.$data)
    console.log(document.getElementById('app').innerHTML)
    console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
    console.groupEnd()
  },
  destroyed () {
    console.groupCollapsed('destroyed 实例销毁后状态')
    console.log('%c%s', 'color:MediumVioletRed', 'el     : ' + this.$el)
    console.log(this.$el)
    console.log('%c%s', 'color:MediumVioletRed', 'data   : ' + this.$data)
    console.log(document.getElementById('app').innerHTML)
    console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
    console.groupEnd()
  }
}
</script>

beforeCreatecreated

beforeCreate :在实例初始化完成时,被执行

created :在初始化结束之后会再初始化一些外部注入和一些双向绑定相关的事情时,被执行

这两个钩子函数执行完之后,初始化基本完成了。

beforeCreate 阶段, eldata 都没有被挂载;而在 created 阶段, el 还没被挂在,但 data 已经被挂载了,如下图所示:

初探 Vue 生命周期和钩子函数

这里 el 为啥没有被挂载呢?

初探 Vue 生命周期和钩子函数

看上图,在 created 执行完毕后,它会询问一个条件: 你这个 Vue 实例里是否有 el 这个选项。

如果有就又会询问是否有 template 这个选项:

  • 如果没有 template 就会走右侧的分支,

    • 如果这个实例没有 template ,就会将 el 这个根节点当做模版,来进行渲染
  • 如果有 template 就会走左侧的分支

    • template 作为模版去渲染

beforeMountmounted

beforeMount :执行时,页面还没有被渲染

mounted :执行时,页面已经被渲染了

从图中也可以看出,在 beforeMount 执行时, el 还没有被挂在;当 mounted 执行时, el 被挂载到页面了。

初探 Vue 生命周期和钩子函数

beforeUpdateupdated

beforeUpdate :数据被改变,还没渲染之前会被执行

updated :数据被改变,渲染完成后会被执行

初探 Vue 生命周期和钩子函数

这张图中有个奇怪的现象,为什么在 beforeUpdateupdated 两个钩子函数中, elmsg 都是一样呢? beforeUpdate 执行是不应该是老数据嘛,怎么这里也是最新的数据了?

因为这里的 el 是虚拟 dom ,不是真实的 dom ,和 data 都是对象,在加上 console.log 这里是个异步操作,当你点开 console.log 时,其实代码早就跑完了,数据已经是最新的了,所以就会看到在这两个函数中输出结果是一样的了。

可以用 document.getElementById('app').innerHTML 获取真实的 Dom 结构,这时我们就可以看到这两处不一样的地方了。

beforeDestroydestroyed

调用 vm.$destroy() 方法可对实例销毁

beforeDestroy :实例被销毁前被执行

destroyed :实例被销毁后被执行

activateddeactivated

activated :使用 keep-alive 标签时会被触发

deactivatedkeep-alive 标签停止调用时会被触发

总结

created :挂载之前需要做的一些事情可以在放在这里面,比如页面加载时 loading 动画

mounted :向后端发请求,可以放在这个函数中。

这两个钩子函数使用时机重叠部分很多,反正是怎么方便怎么来就是了。

参考资源

  1. Vue2.0 探索之路——生命周期和钩子函数的一些理解
  2. vue2 为什么beforeUpdate时的$el 和$data与updated时的一样
  3. JavaScript:钩子函数与回调函数的区别

以上所述就是小编给大家介绍的《初探 Vue 生命周期和钩子函数》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Essential C++中文版

Essential C++中文版

[美] Stanley B. Lippman / 侯捷 / 华中科技大学出版社 / 2001-8 / 39.80元

书中以4个面向来表现C++的本质:procedural(程序性的)、generic(泛型的)、object-based(个别对象的)、object-oriented(面向对象的),全书围绕着一系列逐渐繁复的程序问题,以及用以解决这些问题的语言特性。循此方式,读者不只学到C++的函数和结构,也会学习到它们的设计目的和基本原理。一起来看看 《Essential C++中文版》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

html转js在线工具
html转js在线工具

html转js在线工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具