vue - 生命周期第二次学习与理解

简介: 对于刚接触vue一两个月、才仅仅独立做过一两个vue项目的小白来说,以前一直自我感觉自己知道vue的生命周期,直到前两天去面试,面试官让我说一下vue的生命周期。。。其实我的心中是有那张图的,但是因为学习、分析的年代久远,心中有图却不知道怎么表述,成了个能发声的哑巴,最后也就只能按顺序说出了那几个钩子函数,真是憋足了气!直到今天一鼓作气二刷生命周期,我才恍然大悟,原来我之前的理解中,潜意识里一直是把那几个钩子函数当做了vue的生命周期!简直了,想想那天,面试官肯定在心里把我鄙视死了吧!好了不扯了,直接说我今天看完后,自我感觉还很好的新的理解吧。

对于刚接触vue一两个月、才仅仅独立做过一两个vue项目的小白来说,以前一直自我感觉自己知道vue的生命周期,

直到前两天去面试,面试官让我说一下vue的生命周期。。。

其实我的心中是有那张图的,但是因为学习、分析的年代久远,心中有图却不知道怎么表述,成了个能发声的哑巴,

最后也就只能按顺序说出了那几个钩子函数,真是憋足了气!

直到今天一鼓作气二刷生命周期,我才恍然大悟,原来我之前的理解中,潜意识里一直是把那几个钩子函数当做了vue的生命周期!

简直了,想想那天,面试官肯定在心里把我鄙视死了吧!

好了不扯了,直接说我今天看完后,自我感觉还很好的新的理解吧。

也许日后再深入接触后,会发现今天的理解也很浅显,但是至少今天比我前天好多了哈哈。

 

生命周期:就是从一个组件或者实例开始被初始化、创建开始到这个实例被销毁或者结束的一个过程。

     这个过程比如官网表述的:在过程中需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等

       同时,在这个过程中vue给我们提供了很多的方法,也就是所说的生命周期钩子函数。

     在实例生命周期的不同阶段借助这些钩子函数,用户在不同阶段添加自己的代码

由此:真正的生命周期是一个流程,而不是单单那几个钩子函数,钩子函数只是用来在流程的不同阶段帮助我们做更多的事情。

 

在我粗浅的理解下,我暂时把vue的生命周期统分成五大区块

一、创建(初始化)

二、查找与处理(找到组件并渲染)

三、挂载(插入)

四、更新(重新渲染并插入)

五、销毁(卸载所有)

 其中每一大块又分几个小的步骤,但是大体规律又是如出一辙:

  • 本区块开始前(一个区块流程开始的钩子告诉你)
  • 本区块开始中
  • 本区块开始后(一个区块流程完毕的钩子告诉你)

好像都是废话哈哈,但我真的对这一点的感受很深刻。

 

接下来一个一个来

就像我们人从生下来到死这么一个过程,要有这个流程,先得开始:

一、创建部分

new Vue(  这句代码,初始化一个vue实例,开始创建一个vue对象

 生命周期开始,init event初始化事件,为当前实例做基础配置;

 

创建之前,这里提供一个钩子函数,beforeCreate 开始创建钩子,

  这个时候还啥也没做呢,页面一片空白,可以在页面中先展示一个loading组件,给用户一个友好体验;

 

创建中,init injections & reactivity 创建过程中,data属性被成功绑定,dom未生成;

 

创建之后,这里提供一个钩子函数,created 创建完毕钩子,

  这个时候vue对象实例化完毕,dom依旧未生成,页面空白,

  但是,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。

  可以在这里ajax获取数据赋给data属性了,以便日后使用;

 

二、查找部分

也就是new Vue()括号里边的参数开始被执行解析的过程:

 

new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App }
})

 

new Vue({
  render (h) {
    return h('div', this.hi)
  }
})

查找el属性的对应内容,el对应的DOM 元素作为 Vue 实例的挂载目标

  如果值可以被找到,那么实例将立即进入编译过程

  如果找不到,就去查是否在括号后边挂载了$.mount()并有内容,用于手动开启编译

    以上官网解说:“如果在实例化时存在el这个选项,实例将立即进入编译过程,否则,需要显式调用 vm.$mount() 手动开启编译。”

    官网:https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-DOM

  如果都没找到,生命周期结束;

 

如果顺利的都找到了,就继续往下查找{}内的下一个属性template

  如果template对应的值当中有组件或者有html内容,那么也算查找成功,

  如果为空,继续查找render属性值是否为空

 

紧接着,如果{}选项中存在渲染函数render,

  那么template将被忽略,因为render渲染函数是字符串模板的代替方案,

    render可以让你发挥 JavaScript 最大的编程能力,而不用写template的静态模板

  如果没有或为空,template字符串模板将会替换挂载的元素,即el的属性值

    挂载元素el的内容都将被忽略,除非模板template的内容有分发插槽。

  如果template和render都不存在,则生命周期结束。

 

查找阶段汇总:

  Vue 选项中的 render 函数若存在,则 Vue 构造函数不会从 template 选项或通过 el 选项指定的挂载元素中提取出的 HTML 模板编译渲染函数。

 

至此,食材都准备好了,vue大厨开始开工吧!

此时,将template里的内容放到render函数中开始渲染处理,即执行render方法渲染template里的内容。

(这里是对vue的语法进行解析吗?)

 

题外话:

el其实就是日后要挂载vue组件的一个目标点,如果连目标都找不到,还活着干嘛,干脆结束

template/render就是日后要做的事情,如果都不知道自己接下来要去做什么,还活着干嘛,干脆也结束

 

菜都准备好了总要上桌吧!

所有的dom结构都被渲染好了,vue语法也被解析成正常的html内容了,总要放到页面展示了吧:

三、挂载部分

开始挂载之前,这里提供一个钩子函数,beforeMount挂载前钩子,

  编译template里的内容并在虚拟dom中执行,页面上依旧没有任何展示;

 

挂载中,要做的事就是创建vm$.el,并替换到el元素,

  这一段我也不是太理解,大概感觉就是将#app的那段空的div换成刚才vue生成好的虚拟dom;

 

挂载完毕,这里提供一个钩子函数,mounted挂载完毕钩子,

  el 被新创建的 vm.$el 替换,并挂载到实例上去

  至此,所有的dom结构和数据都被展示到页面当中,

    这时可以做一些事情,比如关掉之前展示的loading;

 注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted

 

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

 

nextTick:在dom结构更新后使用这个方法获取最新的dom结构  

 

 

生命周期到这里,也算初步完成了他的使命,

  如果是一个纯静态页不做任何修改展示的话,根本没必要用到生命周期的后两区块内容了。

但是如果在mounted之后再对实例中的data属性做操作的话,就会走进生命周期的另一个阶段:更新

四、更新部分

依旧是那个套路,触发了更新的开关后,会给一个开始更新的回调:

更新之前,这里有一个钩子函数,beforeUpdate开始更新前钩子,

  在这个钩子里可以提供一个弹窗提示用户确认跟新啥的。或者再展示一个loading;

  也可以手动移除已添加的事件监听器

 

更新中,vue实例要开始将旧数据替换为新数据,在虚拟dom中重新渲染,

  虚拟dom开始改变,但是页面这时没有任何变化,因为只是改的虚拟dom,还并未真正修改dom结构;

 

更新完毕,这里有一个钩子函数,updated更新后钩子,

  这时真正的dom结构被彻底替换,页面展示上也会发生改变,

    在这个钩子里可以提供一个弹窗告诉用户更新完毕。同时去掉loading弹层啥的;

 

注意: updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick 替换掉 updated

 

updated: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been re-rendered
  })
}

 

  

 

如果执行了vm.$destory,就会进入到最后一个部分

五、销毁部分

同上

开始销毁vue实例之前,会有一个钩子函数提示开发者组件要开始销毁:beforeDestory开始销毁钩子,

  在这个钩子中我们可以提醒用户是否删除等,或者做一些开发者与业务有关的相关操作;

 

销毁中,vue这时的主要目标就是卸载,就像人要洗澡前各种脱一样(具体就不要想象了!),

  他要卸载在身上的各种监听、各种事件, 各种绑定以及各种子组件实例销毁,感觉像毁灭一切

    比如watchers(我没用过没有发言权)、子组件child components、事件event;

 

销毁后,这时再次提供最后一个钩子函数,destoryed销毁完毕,

  在这里我们可以提示用户删除完毕啥的,也可以清空我们自己的定时器或者做一些其他善后工作;

 

到这一步,此次整个vue实例的生命周期就彻底结束了。

 

以上,仅是自己了解vue后再刷生命周期图的二次理解,仅代表个人的理解,

不一定完全正确,欢迎指正,最后也别全信。毕竟绝知此事要躬行。

 

最后,贴一张一刷时自己备注的官网生命周期图,对照着图再去理解我的总结应该更好。

 

 

哇塞,认真学习了16分钟,记录草稿后,加上自己理解对树讲述了两遍后,一口气2000字的心得写下来了。

真的是画竹要先胸有成竹才行!

2018-06-09  14:07:16

目录
相关文章
|
2天前
|
缓存 JavaScript 前端开发
《基础篇第4章:vue2基础》:使用vue脚手架创建项目
《基础篇第4章:vue2基础》:使用vue脚手架创建项目
12 3
|
2天前
|
缓存 JavaScript
Vue 中 computed 与 method 的区别
【10月更文挑战第15天】computed 和 method 是 Vue 中两个重要的选项,它们在功能和特点上存在着明显的区别。理解并合理运用它们的区别,可以帮助我们构建更高效、更具可维护性的 Vue 应用。在实际开发中,要根据具体情况灵活选择使用,以满足不同的需求。
5 2
|
2天前
|
JavaScript 搜索推荐 UED
vue的自定义指令
【10月更文挑战第14天】Vue 自定义指令为我们提供了一种强大的工具,使我们能够更灵活地控制和扩展 Vue 应用的行为。通过合理地使用自定义指令,可以提高开发效率,增强应用的功能和用户体验。
|
3天前
|
JavaScript
|
1天前
|
JavaScript 前端开发 Java
vue2知识点:Vue封装的过度与动画
vue2知识点:Vue封装的过度与动画
7 0
|
2天前
|
JavaScript UED
在 Vue 中使用自定义指令
【10月更文挑战第14天】通过合理地使用自定义指令,可以为 Vue 应用带来更多的灵活性和扩展性,提高开发效率和用户体验。
|
3天前
|
JavaScript 前端开发 API
深入探索挖掘vue3 生命周期
【10月更文挑战第10天】
13 0
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
1042 0
|
5天前
|
JavaScript 前端开发 开发者
Vue v-for 进阶指南:in 与 of 的区别及应用场景 | 笔记
Vue.js 中的 v-for 是强大的遍历指令,但其中的 in 和 of 关键字往往被开发者忽视。尽管它们的用法相似,但适用的场景和数据结构却各有不同。本文将详细探讨 v-for 中 in 和 of 的区别、适用场景以及在实际开发中的最佳使用时机。通过理解它们的差异,你将能够编写更加高效、简洁的 Vue.js 代码,灵活应对各种数据结构的遍历需求。
40 6
|
5天前
|
缓存 JavaScript 前端开发
Vue 中动态导入的注意事项
【10月更文挑战第12天】 在 Vue 项目中,动态导入是一种常用的按需加载模块的技术,可以提升应用性能和效率。本文详细探讨了动态导入的基本原理及注意事项,包括模块路径的正确性、依赖关系、加载时机、错误处理、缓存问题和兼容性等,并通过具体案例分析和解决方案,帮助开发者更好地应用动态导入技术。