Vue核心知识-Vue的生命周期方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/grapelove01/article/details/82460960

有哪些生命周期方法

把所有生命周期打印一遍

import Vue from 'vue'

const app = new Vue({
  // el: '#root',
  template: '<div>{{text}}</div>',
  data: {
    text: 0
  },
  beforeCreate () {
    console.log(this, 'breforeCreate')
  },
  created () {
    console.log(this, 'created')
  },
  beforeMount () {
    console.log(this, 'beforeMount')
  },
  mounted () {
    console.log(this, 'mounted')
  },
  beforeUpdate () {
    console.log(this, 'beforeUpdate')
  },
  updated () {
    console.log(this, 'updated')
  },
  activated () {
    console.log(this, 'activated')
  },
  deactivated () {
    console.log(this, 'deactivated')
  },
  beforeDestroy () {
    console.log(this, 'beforeDestroy')
  },
  destroyed () {
    console.log(this, 'destroyed')
  }
})

app.$mount('#root')

显示结果

结果依次显示 “breforeCreate” “created” “beforeMount” “mounted”,说明在new Vue()时,这四个方法执行了。

breforeMount 和 mounted

如果把el:'#root'注释掉,就只显示“breforeCreate” “created” ,因为mount的作用就是把vue组件生成的html内容,挂载到html节点上,所以当我们没有指定el:'#root'或通过$mount进行,是不会挂载到html节点上的。

breforeCreate 和 created

而 breforeCreate created 在初始化阶段就执行了。

beforeUpdate 和 updated

数据更新时,才会执行。

例如,每一秒钟更改数据,相应的每秒都会执行这两个生命周期

setInterval(() => {
  app.text = app.text += 1
}, 1000)

beforeDestroy 和 destroyed

vue实例销毁时执行。

例如,设置一秒钟后销毁,控制台就会显示 “beforeDestroy” 和 “destroyed”

setTimeout(() => {
  app.$destroy()
}, 1000)

activated 和 deactivated

和vue中一个原生的组件 keep-alive有关系。

分别打印出不同周期对应的$el

beforeCreate () {
    console.log(this.$el, 'breforeCreate')
  },
  created () {
    console.log(this.$el, 'created')
  },
  beforeMount () {
    console.log(this.$el, 'beforeMount')
  },
  mounted () {
    console.log(this.$el, 'mounted')
  },

显示结果

undefined "beforeCreate"
undefined "created"
<div id="root"></div> "beforeMount"
<div>0</div> "mounted"

可以看到

beforeCreate 和 created 的 $el 是undefined,所以 beforeCreate 和 created 阶段是不能进行dom操作的,因为拿不到 dom 节点。

brforeMount 时,$el变成了我们写在 html 中 div 节点。

mounted 时, $el变成了 template 中的html,说明覆盖了html原来的 div 节点。

mounted之后,我们调用的所有生命周期方法,拿到的节点,都是渲染之后的节点。

所以一般

  • 做 dom 相关操作会在 mounted 阶段
  • 数据相关操作,可以在 created 或 mounted 阶段

生命周期的调用顺序

beforeCreate created beforeMount mounted 都是一次性的,组件只会调用一次。

beforeMount mounted 在服务端渲染,是不会被调用的,服务端渲染过程中,只会调用 beforeCreate created,因为 mount 是和 dom 操作相关的,服务端根本没有 dom 执行的环境, 所以不会有。

当数据发生变化时,beforeUpdate 和 updated 会调用。

当组件销毁时,beforeDestroy 和 destroyed 会调用。

声明周期中 VUE 实例有哪些区别

在不同的生命周期阶段,this.$el是不同的,而在 mounted之后,一般不会改动 this.$el,而是围绕阶段做某些操作,要尽量避免 this.$el的变动,它会导致一些 vue 错误。

理解生命周期就是理解一张图

Vue 实例生命周期

  1. init,new Vue() 先执行 init 操作,这个操作是默认执行的。
    1. init Events $ Lifecycle,调用 beforeCreate,所以此时,事件OK,但reactive不OK,所以这个阶段不要修改数据 data 中的数据
    2. init injections $ reactivity,调用 createdajax请求获取数据赋值,最早在 created 阶段做
  2. 判断 Has “el” option
    1. 如果有,执行下一步。
    2. 如果没有,等我们调用 vm.$mounted(el)
  3. 判断 Has “template” options
    1. 如果有,把 template 解析生一个 render 函数。render 函数会用 template 中的 html 去覆盖 html 中的 div 标签。在使用 .vue 文件进行开发的过程中,是没有 template 的,我们在 .vue 文件中写的 template 都经过了 vue-loader 处理,直接变成了 render 函数,放在vue-loader 解析过的文件中;这样做的好处,把 template 解析成 render 函数,比较耗时,vue-loader 处理后,我们在页面上执行代码时,效率会变高。
    2. 如果没有,Compile el’s outerHTML as template
  4. 有了 render 函数之后
    1. beforeMount 执行
  5. 执行 render 函数
    1. Create vm.$el and replace “el” with it
  6. 执行 render 函数之后
    1. mounted 执行
  7. mounted之后,实例创建完成,后续过程,都是通过外部触发进行的。
  8. 当数据变化时
    1. beforeUpdate 执行
    2. Virtual DOM re-render and patch
    3. updated 执行
  9. 当组件销毁时
    1. beforeDestroy 执行
    2. Teardown watchers,child comonents and event listeners
    3. destroyed 执行

render 函数

直接使用 render 函数和使用 template 一样的。

import Vue from 'vue'

const app = new Vue({
  // template: '<div>{{text}}</div>',
  data: {
    text: 0
  },
  render (h) {
    return h('div', {}, this.text) // 参数1,创建的标签;参数2,对象配置;参数3,标签内容
  },
})

app.$mount('#root')

render 函数执行时机

render (h) {
    console.log('render function invoked')
    return h('div', {}, this.text)
  },

控制台结果

undefined "beforeCreate"
undefined "created"
<div id="root"></div> "beforeMount"
render function invoked
<div>0</div> "mounted"

在beforeMount 和 mounted 之间执行的

renderError 方法

renderError 方法,只有在开发时,才会被调用,正式打包上线时,不会被调用。帮助我们调试 render 中的错误。renderError 方法,只有在本组件 render 出现错误时,才会被调用;如果是子组件报错,是不会被捕获到的。

当 render 函数报错时,renderError 方法会执行。

render (h) {
    throw new TypeError('render error')
    // console.log('render function invoked')
    // return h('div', {}, this.text)
  },
  renderError (h, err) {
    return h('div', {}, err.stack)
  }

errorCaptured 方法

可以用在正式开发环境中,帮助我们搜集线上的错误。如果在根组件使用这个方法,而根组件的子组件报的任何错误都可捕捉到,除非子组件把向上冒泡停止掉。

errorCaptured 方法使用与 renderError 相似,唯一的区别是:errorCaptured 会向上冒泡,并且正式环境可以使用。

总结

生命周期的执行顺序,调用时机,不同时机进行哪些操作,不同生命周期this.$el的区别。

猜你喜欢

转载自blog.csdn.net/grapelove01/article/details/82460960
今日推荐