【Vue】详解Vue生命周期

 

(这里的红边圆角矩形内的都是对应的Vue实例的钩子函数)

在beforeCreate和created钩子函数间的生命周期

 

在beforeCreate和created之间,进行数据观测(data observer) ,也就是在这个时候开始监控data中的数据变化了,同时初始化事件
 

created钩子函数和beforeMount间的生命周期

 

对于created钩子函数和beforeMount间可能会让人感到有些迷惑,下面我就来解释一下:

el选项的有无对生命周期过程的影响

首先系统会判断对象中有没有el选项
有el选项,则继续编译过程
没有el选项,则中止编译,也意味着暂时中止了生命周期,直到vm.$mount(el)
下面我展现一下:
复制代码
new Vue({
  el: '#app',
  beforeCreate: function () {
    console.log('调用了beforeCreat钩子函数')
  },
  created: function () {
    console.log('调用了created钩子函数')
  },
  beforeMount: function () {
    console.log('调用了beforeMount钩子函数')
  },
  mounted: function () {
    console.log('调用了mounted钩子函数')
  }
})
复制代码

 

demo以下:

 

能够看到,在el选项填写且正确的时候,生命周期将正常进行
 
而当咱们把el去掉:
复制代码
new Vue({
  beforeCreate: function () {
    console.log('调用了beforeCreat钩子函数')
  },
  created: function () {
    console.log('调用了created钩子函数')
  },
  beforeMount: function () {
    console.log('调用了beforeMount钩子函数')
  },
  mounted: function () {
    console.log('调用了mounted钩子函数')
  }
})
复制代码

 

demo:
 

 

能够看到,生命周期的钩子函数 执行到created就结束了
而当咱们不加el选项, 可是手动执行vm.$mount(el)方法的话,也可以使暂停的生命周期进行下去,例如:
复制代码
var vm = new Vue({
  beforeCreate: function () {
    console.log('调用了beforeCreat钩子函数')
  },
  created: function () {
    console.log('调用了created钩子函数')
  },
  beforeMount: function () {
    console.log('调用了beforeMount钩子函数')
  },
  mounted: function () {
    console.log('调用了mounted钩子函数')
  }
})
vm.$mount('#app')
复制代码

 

demo以下,能够看到,这个时候虽然对象中没有el参数,但经过$mount(el)动态添加的方式,也可以使生命周期顺利进行
 

 

template参数选项的有无对生命周期的影响

 

 

1.若是Vue实例对象中有template参数选项,则将其做为模板编译成render函数
2.若是没有template参数选项,则将外部的HTML做为模板编译(template),也就是说,template参数选项的优先级要比外部的HTML高
3.若是1,2条件都不具有,则报错
 
咱们能够把模板写在template参数选项中:
new Vue({
  el: '#app',
  template: '<div id="app"><p>模板在templated参数中找到了哟~</p></div>'
})
demo:

 

 

 

也能够把参数选项写在外部HTML中,像这样:
 
外部HTML:
<div id="app"><p>模板是在外部HTML中找到的~</p></div>
建立对象实例:
new Vue({
  el: '#app'
})

 

demo:

 

那么有趣的问题来了,当模板同时放在template参数选项和外部HTML中,会怎样呢?
例如:
外部HTML:
<div id="app"><p>模板是在外部HTML中找到的~</p></div>

 

 
建立Vue实例(包含template参数选项)
new Vue({
  el: '#app',
  template: '<div id="app"><p>模板在templated参数中找到了哟~</p></div>'
})

 

demo以下:

 

很显然,正如我上面下的结论同样,最终显示的是“模板在templated参数中找到了哟~”而不是“模板是在外部HTML中找到的~”,由于template参数的优先级比外部HTML的优先级要高
 
【注意】
1.为何判断el要发生在判断template前面呢
 
由于Vue须要经过el的“选择器”找到对应的template。总结一下上述的过程,Vue经过el参数去找到对应的template。而后,根据el参数给出的“选择器”,首先去Vue实例对象自己的template选项参数中找,若是没有template参数,则到外部HTML中寻找,找到后将模板编译成render函数
 
2.实际上,在Vue中,有render函数这个选项,它以createElement做为参数,作渲染操做。固然你也能够不调用createElement,而直接嵌入JSX(学习react的同窗对此应该很熟悉吧)。
复制代码
new Vue({
  el: '#demo',
  render (createElement) {
    return (....)
  }
})
复制代码

 

【注意】render选项参数比template更接近Vue解析器!因此综合排列以下:
render函数选项  > template参数  > 外部HTML
 

Vue的编译过程——把模板编译成 render 函数

Vue的编译其实是指Vue把模板编译成 render 函数的过程
 
咱们能够经过Vue.compile这个实时编译模板的函数来看一看:
用官方文档的例子作个解释:
复制代码
<div>
  <header>
    <h1>I'm a template!</h1>
  </header>
  <p v-if="message">
    {{ message }}
  </p>
  <p v-else>
    No message.
  </p>
</div>
复制代码

 

  
会被渲染成
function anonymous() {
  with(this){return _c('div',[_m(0),(message)?_c('p',[_v(_s(message))]):_c('p',[_v("No message.")])])}
}

 

beforeMount和mounted钩子函数间的生命周期

 

 

对于这一点, 我也感到有些迷惑,百度后以后也没什么头绪,最后我思考的结果是这样的:正由于render函数和template选项的“优先级”比外部HTML要高,因此,最后通常会存在一个外部HTML模板被Vue实例自己配置的模板所“替代”的过程也就是上图所说的 “replace”
 
(若是你们有不一样意见也能够在评论处一块儿讨论)
 

beforeUpdate钩子函数和updated钩子函数间的生命周期

 

 

在Vue中,数据更改会致使虚拟 DOM 从新渲染,并前后调用beforeUpdate钩子函数和updated钩子函数
 
但要注意一点: 重渲染(调用这两个钩子函数)的前提是被更改的数据已经被写入模板中!!(这点很重要)
例如:
复制代码
var vm = new Vue({
  el: '#app',
  data: {
    number: 1
  },
  template: '<div id="app"><p></p></div>',
  beforeUpdate: function () {
    console.log('调用了beforeUpdate钩子函数')
  },
  updated: function () {
    console.log('调用了updated钩子函数')
  }
})
 
vm.number = 2
复制代码

 

 

 

控制台上并无如咱们预料那样输出调用两个钩子函数的文本
而当咱们改为
复制代码
var vm = new Vue({
  el: '#app',
  data: {
    number: 1
  },
  // 在模板中使用number这个数据
  template: '<div id="app"><p>  {{ number }} </p></div>',
  beforeUpdate: function () {
    console.log('调用了beforeUpdate钩子函数')
  },
  updated: function () {
    console.log('调用了updated钩子函数')
  }
})
 
vm.number = 2
 
复制代码

 

 

 
这个时候,调用两个钩子函数的文本就被输出来了
总之,只有Vue实例中的数据被“写入”到咱们的模板中,它的改变才能够被Vue追踪,重渲染从而调用 beforeUpdate钩子函数和updated钩子函数
 

beforeDestroy和destroyed钩子函数间的生命周期

 

 

beforeDestroy钩子函数在实例销毁以前调用。在这一步,实例仍然彻底可用。
 
destroyed钩子函数在Vue 实例销毁后调用。调用后,Vue 实例指示的全部东西都会解绑定,全部的事件监听器会被移除,全部的子实例也会被销毁。
 
【注意】就如同调用在Vue实例上调用$mounted会使暂停的生命周期继续同样,调用$destroy()会直接销毁实例
相关文章
相关标签/搜索