vue-的生命周期

有哪些生命周期方法

把所有生命周期打印一遍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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 数据更新时,才会执行。 例如,每一秒钟更改数据,相应的每秒都会执行这两个生命周期

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

beforeDestroy 和 destroyed vue实例销毁时执行。 例如,设置一秒钟后销毁,控制台就会显示 “beforeDestroy” 和 “destroyed”

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

activated 和 deactivated 和vue中一个原生的组件 keep-alive有关系。 分别打印出不同周期对应的$el

1
2
3
4
5
6
7
8
9
10
11
12
beforeCreate () {
console.log(this.$el, 'breforeCreate')
},
created () {
console.log(this.$el, 'created')
},
beforeMount () {
console.log(this.$el, 'beforeMount')
},
mounted () {
console.log(this.$el, 'mounted')
},

显示结果

1
2
3
4
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 错误。

  1. init,new Vue() 先执行 init 操作,这个操作是默认执行的。
    1. init Events $ Lifecycle,调用 _beforeCreate_,所以此时,事件OK,但reactive不OK,所以这个阶段不要修改数据 data 中的数据。
    2. init injections $ reactivity,调用 created ,ajax请求获取数据赋值,最早在 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 一样的。

1
2
3
4
5
6
7
8
9
10
11
12
13
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 函数执行时机

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

控制台结果

1
2
3
4
5
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 会向上冒泡,并且正式环境可以使用。

  • 版权声明: 本博客所有文章,未经许可,任何单位及个人不得做营利性使用!转载请标明出处!如有侵权请联系作者。
  • Copyrights © 2015-2020 翟天野

请我喝杯咖啡吧~