美文网首页
对Vue生命周期的理解

对Vue生命周期的理解

作者: 益码凭川 | 来源:发表于2020-03-10 16:02 被阅读0次

一、生命周期概念

首先,每一个vue实例都有一个完整的生命周期,主要分为五个阶段:创建、初始化、渲染、运行、销毁。 也就是从创建(new Vue())、初始化数据(init)、编译模板(render function)、挂载Dom($el)、渲染($mount)→更新(update)→渲染(Virtual Dom re-Render)、销毁(destory)等一系列过程,我们称这是Vue的生命周期。

通俗说就是Vue实例从创建到销毁的过程,就是生命周期。

二、vue生命周期图解

三、具体详解

1.创建阶段

new Vue() 创建

表示开始创建一个vue实例对象。

2.初始化阶段

创建之后这个时候就会调用this._init()方法,

letuid =0Vue.prototype._init =function(options){constvm= thisvm._uid = uid++  // 组件唯一标识vm.$options= mergeOptions(  // 合并optionsresolveConstructorOptions(vm.constructor),options|| {},vm)  ...  initLifecycle(vm) // 开始一系列的初始化  initEvents(vm)  initRender(vm)  callHook(vm,'beforeCreate')  initInjections(vm)  initState(vm)  initProvide(vm)  callHook(vm,'created')  ...if(vm.$options.el) {vm.$mount(vm.$options.el)  }}

2.1 合并options配置

1. 初始化new Vue

在执行new Vue构造函数时,参数就是一个对象,也就是用户自定义配置;会将它和vue之前定义的原型方法、全局API 属性、还有全局的Vue.mixin内的参数,将这些都合并成一个新的options, 最后赋值给一个新的属性$options。

2. 子组件初始化

如果是子组件初始化, 除了合并以上那些外,还会将父组件的参数进行合并, 如有父组件定义在子组件上的event, props 等等。

经过合并之后就可以通过this.options.data访问到用户定义的data函数,this.options.name访问到用户定义的组件名称,这个合并后的属性很重要,会被经常使用到。

2.2 初始化事件和生命周期

刚初始化一个空的vue实例对象,这个时候只有一些生命周期函数和默认的事件,其他的东西都还为创建。

1.initLifecycle(vm)

确认组件(也是vue实例)的父子关系以及初始化vm.$parent, $children实例属性。后面可进行事件的触和数据的传递。

2.initEvents(vm)

主要作用是将父组件在使用v-on 或者 @ 注册自定义事件添加到子组件的事件中心中。

原生事件

在执行initEvent之前模板编译阶段,会判断遇到的是html标签名 还是组件名。

如果是html标签名,就会在转为真是dom之后使用addEventListener注册浏览器原生事件。 当然这个步骤是在挂载dom的最后阶段,这歌时候是初始化阶段,主要处理自定义事件。

自定义事件

在经过合并options 阶段后, 子组件就可以从 vm.$options._parentListeners读取到父组件传过来的自定义事件。 通过updateListeners方法, 它的作用是借助之前定义的$on, $emit方法, 完成父子组件事件的通信。

3. initRender(vm)

主要作用是挂载,将render函数转化为vnode的方法。

exportfunctioninitRender(vm){  vm._vnode = null  ...

  vm._c =(a,b,c,d) =>createElement(vm,a,b,c,d,false)//转化编译器的vm.$createElement =(a,b,c,d) =>createElement(vm,a,b,c,d,true)// 转化手写的  ...}

主要作用是挂载vm._c 和 vm.createElement两个方法,它门只是最后一个参数不同,这两个方法都可以将render函数转为vnode,从命名大家应该可以看出区别,vm.c转换的是通过编译器将template转换而来的render函数;而vm.createElement 两个方法,它门只是最后一个参数不同,这两个方法都可以将render函数转为vnode, 从命名大家应该可以看出区别,vm._c 转换的是通过编译器将template 转换而来的 render 函数; 而 vm.createElement两个方法,它门只是最后一个参数不同,这两个方法都可以将render函数转为vnode,从命名大家应该可以看出区别,vm.c转换的是通过编译器将template转换而来的render函数;而vm.createElement 转换的是用户自定义的 render 函数, 比如:

new Vue({data: {    msg:'hello Vue!'},  render(h) {// 这里的 h 就是vm.$createElementreturnh('span',this.msg);    }}).$mount('#app');

4.callHook(vm, ''beforeCreate)

执行beforeCreate里的内容;

灵魂一问:请问可以在beforeCreate 钩子内通过 this 访问到data中定义的变量么,为什么? 请问这个钩子可以做什么?

是不可以访问的。 因为在vue 初始化阶段, 这个时候data 中的变量还没有挂载到this 上, 这个时候访问值会是 undefined。 beforeCreate 这个钩子在平时业务开发中比较少用。 像插件内部install 方法通过Vue.use 方法安装时一般会选在beforeCreate 这个钩子内执行, vue-router 和 vuex 就是这么干的。

2.3 初始化注入和校验

1. initInjections(vm) 主要作用是初始化inject,可以访问到对应的依赖。

inject 和 provide 是vue@2.2 版本添加的一对需要一起使用的API, 它允许父级组件向它之后的子孙组件提供依赖,让子孙组件无论嵌套多深都可以访问到。

provide : 提供一个对象或是返回一个对象的函数。 inject : 是一个字符串数组或对象。

举一个栗子:

app.vue 根组件export default {  provide() {    return {      app: this    }  },  data() {    return {      info:'hello world!'}  }}child.vue 子孙组件export default {  inject: ['app'],  methods: {    handleClick() {      this.app.info='hello vue 变 world 啦!'}  }}

这样可以简单实现vuex的功能,但是要注意组件之间层级关系,可能会造成混乱的现象。

2. initState(vm)

初始化会被使用到的状态:props、methods、data、computed、watch。

initProps(vm,propOptions)

主要作用是检测子组件接收的值是否符合规则,以及对应的值可以用this直接访问。

initMethods(vm, methods):

主要作用是将methods内的方法挂载到this下。命名规范的检查。不能与props的key重名,以及不能以_、$开头。

initData(vm)

主要作用是初始化data,挂载到this下。

3. initProvide(vm)

主要作用是初始化provide为子组件提供依赖。

4. callHook(vm, 'created')

作用是执行用户定义的created钩子函数,有mixin混入的也一并执行。

灵魂一问:请问methods 内的方法可以使用箭头函数么? 会产生怎样的结果?

答案: 是不可以使用箭头函数的, 因为箭头函数的this是在定义时就绑定的。 在vue的内部, methods 内每个方法的上下文是当前的vm组件实例, methods[key].bind(vm)。 如果使用箭头函数,函数的上下文就变成了父级的上下文, 也就是undefined了, 结果就是通过undefined 访问任何变量都会报错。

在created中,data和methods都已经初始化好了。最早也只能在created里调用methods方法和操作data数据。

另外注意

如果要在created阶段中进行dom操作,就要将操作都放在 Vue.nextTick() 的回调函数中,因为created() 钩子函数执行的时候 DOM 其实并未进行任何渲染,而此时进行 DOM 操作无异于徒劳,所以此处一定要将 DOM 操作的 js 代码放进 Vue.nextTick() 的回调函数中。 一般我们最好不要在created里操作dom。

Vue.nextTick( [callback, context] ):在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

3.渲染阶段

3.1 编译模板

从created到beforeMount的过程中,首先会判断vue实例中有没有el选项,如果有的话则进行下面的编译,但是如果没有el选项,则停止生命周期,直到vue实例上调用vm.$mount(el)。 如果有el,再判断是否有template参数,如果有,则把其当作模板编译成render函数,如果没有,则把外部的html作为模板编译。template中的模板优先级高于outer HTML模板。 在vue对象中还有一个render函数,它是以createElement作为参数,然后做渲染操作,而且我们可以直接嵌入JSX. 综合排名优先级:render函数选项 > template选项 > outer HTML

3.2 beforeMount

此函数进行时,模板已经在内存中编译好了,但是尚未挂载到页面中去,此时,页面还是旧的。

3.3 挂载

这一步,将内存中编译好的模板,替换到浏览器的页面中去。

3.4 mounted

这个节点表示整个vue实例已经初始化完毕了,此时组件已经脱离了创建-渲染阶段,进入到运行阶段。

4.运行阶段

运行阶段的生命周期函数式beforeCreate和created,这个两个事件会根据数据data的改变,有选择性的触发0次或多次。

4.1 beforeUpdate

这个生命周期里,页面中显示的数据还是旧的,但是咱们data的数据是最新的,页面尚未和最新的数据保持同步。

4.2 虚拟Dom重新编译渲染

这一步执行的是:现根据data中最新的数据,在内存中,重新渲染出一份最新的内存DOM树, 当最新的内存DOM树 被更新之后, 会把最新的内存DOM树,重新渲染到真是的页面中去,这个时候就完成了数据从data(Mode层)=> View(视图层)的更新。

4.3 Updated

updated执行时,页面和data已经保持同步了,都是最新的。

5.销毁阶段

5.1 beforeDestory

当执行beforeDestory钩子函数的时候,Vue实例就已经从运行阶段进入到了销毁阶段:

这个时候,实例上所有的data和methods,以及过滤器、指令等等 都还处于 可用状态,此时还没有真正执行销毁的过程。

5.2 destroyed

当执行到destroyed钩子函数的时候,组件已经被完全销毁了,此时Vue实例所有的data、methods、过滤器、指令... 都用不了。

总结:以上就是我所总结的对Vue生命周期的理解,也是参考了各方面的解释,结合自己的理解,对Vue生命周期进行梳理。当梳理了之后,你会发现你对Vue会又更好的理解。

更多内容请访问我的博客网站:http://www.jscwwd.com/article/5e65f4e249a13d1a89caf57c##toc412

相关文章

  • vue学习记录

    vue全家桶 vue生命周期 生命周期的理解 新建项目 ①:cnpm install vue-cli -g (全...

  • 浅谈vue的生命周期

    生命周期 在使用vue的过程中,对vue的生命周期的理解是最基础的开始,也许你不需要全部理解,但对其中最主要的几个...

  • Vue生命周期

    一.个人理解对Vue的生命周期的理解 1.1: beforeCreate: 创建阶段的第一个生命周期函数,组件的P...

  • vue面试必会

    一、对于MVVM的理解? 二、 Vue的生命周期 1.什么是Vue生命周期? 2.vue生命周期的作用是什么? 3...

  • Vue生命周期小结

    Vue框架已日臻成熟,生命周期也算是老生常谈了。网路上也有很多对Vue生命周期的讲解。此处是补充上自己的理解,再次...

  • Day45/100 Vue的生命周期

    写在前面的话 Vue生命周期贯穿Vue的整体思想的理解~灰常重要 (一)Vue生命周期全景图 (二)新建Vue实例...

  • vue的生命周期

    目录:1.对于MVVM的理解2.Vue的生命周期3.什么是vue生命周期?4.vue生命周期的作用是什么?5.vu...

  • Vue2.0生命周期钩子

    给大家分享一下我对Vue2.0的生命周期钩子的理解与用法 一、生命周期图示 二、生命周期分解 1、beforeCr...

  • 前端面试问题

    1.对于MVVM的理解 2.开发中常用的指令有哪些 3.请详细说下你对vue生命周期的理解 4.vue-route...

  • Vue生命周期

    我对vue生命周期的理解可以归纳为一句话,就是~~在正确的时间做正确的事 随着vue版本的更新,生命周期也在发生变...

网友评论

      本文标题:对Vue生命周期的理解

      本文链接:https://www.haomeiwen.com/subject/ftxxhhtx.html