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()会直接销毁实例
 
 

【Vue】详解Vue生命周期的更多相关文章

  1. Vue 实例详解与生命周期

    Vue 实例详解与生命周期 Vue 的实例是 Vue 框架的入口,其实也就是前端的 ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进 ...

  2. 05-Vue入门系列之Vue实例详解与生命周期

    Vue的实例是Vue框架的入口,其实也就是前端的ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进行对整个Vue实例生成.编译.挂着. ...

  3. Vue入门系列(五)Vue实例详解与生命周期

    Vue官网: https://cn.vuejs.org/v2/guide/forms.html#基础用法 [入门系列] (一)  http://www.cnblogs.com/gdsblog/p/78 ...

  4. Vue实例详解与生命周期

    http://www.jianshu.com/p/b5858f1e6e76 Vue的实例是Vue框架的入口,其实也就是前端的ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己 ...

  5. 【05】Vue 之 实例详解与生命周期

    Vue的实例是Vue框架的入口,其实也就是前端的ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进行对整个Vue实例生成.编译.挂着. ...

  6. maven详解之生命周期与插件

    Maven是一个优秀的项目管理工具,它能够帮你管理编译.报告.文档等. Maven的生命周期: maven的生命周期是抽象的,它本身并不做任何的工作.实际的工作都交由"插件"来完成 ...

  7. 详解Vue.js 技术

    本文主要从8个章节详解vue技术揭秘,小编觉得挺有用的,分享给大家. 为了把 Vue.js 的源码讲明白,课程设计成由浅入深,分为核心.编译.扩展.生态四个方面去讲,并拆成了八个章节,如下: 准备工作 ...

  8. vue基本配置和生命周期

    Vue的实例是Vue框架的入口,其实也就是前端的ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进行对整个Vue实例生成.编译.挂着. ...

  9. Vue2.5笔记:Vue的实例与生命周期

    理解与认识 Vue 的实例是我们学习 Vue 非常重要的一步,也是非常必须的,因为实例是它的一个起点,也是它的一个入口,只有我们创建一个 Vue 实例之后,我们才行利用它进行一些列的操作. 首先 Vu ...

  10. 详解vue的数据binding原理

    自从angular火了以后,各种mv*框架喷涌而出,angular虽然比较火,但是他的坑还是蛮多的,还有许多性能问题被人们吐槽.比如坑爹的脏检查机制,数据binding是受人喜爱的,脏检查就有点…性能 ...

随机推荐

  1. Git 使用记录

    在win7平台已经安装好了git的情况下: 1,Git 本地仓库建立与使用步骤: (2)新建立文件夹: $ mkdir learngit $ cd learngit $ pwd /Users/mich ...

  2. 全景智慧城市常诚——一个实体商家“自剖”VR全景的势在必得

    谈起"智慧城市",你的心中是否充满了期待?随着互联网的发展,人们对于"智慧城市"的需求越来越迫切.现在想想,我也算是首批入驻全景智慧城市的商家之一了.在各种连锁 ...

  3. jquery中html、text、val回调函数

    先扫盲: 摘自菜鸟教程:jQuery 方法:text().html() 以及 val()拥有回调函数. 回调函数有两个参数:被选元素列表中当前元素的下标,以及原始(旧的)值.然后以函数新值返回您希望使 ...

  4. JavaSE教程-02Java基本语法

    1.注释 什么是注释 用于解释说明程序作用的文字 Java中注释分类格式 单行注释 格式: //注释文字 多行注释 格式: /* 注释文字 */ 文档注释 格式:/* 注释文字 / 2.关键字 什么是 ...

  5. Javascript加载执行顺序

    本文主要内容 一.不同位置的script标签执行顺序 二.document.ready和window.onload的区别 一.不同位置的script标签执行顺序 整个加载的过程从解析头部开始,比如ht ...

  6. 写个百万级别full-stack小型协程库——原理介绍

    其实说什么百万千万级别都是虚的,下面给出实现原理和测试结果,原理很简单,我就不上图了: 原理:为了简单明了,只支持单线程,每个协程共享一个4K的空间(你可以用堆,用匿名内存映射或者直接开个数组也都是可 ...

  7. Azure 基础:Table storage

    Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table.其中的 Table 就是本文的主角 Azure Tabl ...

  8. jsp,jquery,spring mvc 实现导出文件

    需求:在界面上选择一个日期,然后点击导出按钮,直接导出选择月份的考勤excel文件. 这篇文章主要是介绍如何下载文件! jsp中代码: <div class="form-group&q ...

  9. 基于Jmeter的轻量级接口压力测试(一)

    一.操作步骤: 1.在测试计划下新增一个线程组,并在线程组下新增一个http请求: 2.读取配置文件中的参数:在添加的http请求下添加配置元件-CSV DATA SET CONFIG 3.配置待测试 ...

  10. Django rest framework 自定义Exception

    使用Dango rest framework时,有时需要raise APIException到前端,为了统一错误返回格式,我们需要对exception的格式进行调整. 方法: 1. 在project/ ...