Vue源码系列之生命钩子beforeCreate&created

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue源码系列之生命钩子beforeCreate&created相关的知识,希望对你有一定的参考价值。

参考技术A 在实习面试中,Vue相关被问到最多的就是围绕生命周期函数内部所作的一些操作,很多朋友可能了解的就是官网的下图,有时候倒霉遇上硬核点的面试官,深入问些东西就会被怼的哑口无言,本文就是在之前源码的基础上,分析一下,生命周期函数究竟发生了什么
先上图

在分析每个钩子之间究竟干了什么之前,先来看看钩子是怎么触发的,以第一个钩子为例

调用callHook函数并向其传入this和'beforeCreate'字符串,那来看看callHook函数究竟是何方神圣

注意到,该函数一开始,也就是钩子函数进入准备触发前,进行了一个pushTarget()的操作,注释写的是“在钩子函数触发时,禁用依赖收集”,那这个操作是干嘛呢

言归正传,禁用了依赖收集后,创建handlers数组存入合并后options的hook,本例中就是找自定义或者继承来的beforeCreate钩子,然后在invokeWithErroeHandling函数中以此触发,顺序是先触发父级,后自己定义的
而这个invokeWithErroeHandling函数如下

该函数直接就在内部call了钩子,所以钩子内部的this指向vm实例
以上就是钩子函数的触发过程,下面来看不同的生命周期之间究竟干了什么

beforeCreate之前

beforeCreate之后到created

1.对于props:合法化,缓存key进数组方便下次迭代,defineReactive
2.对于data:检验props,methods中是否有重名属性,defineReactive
3.对于methods:代理到vm实例上,方便使用this.method.name调用
4.对于computed:封装成watcher并用该watcher的value缓存该计算属性的value,再在每个计算属性上劫持一层getter和setter,在第一次调用getter的时候,取得最新的value,并将依赖缓存下来,之后再依赖不变的前提下,getter只返回watcher的value而不是又去取一遍值,再依赖发生变化的时候,通知watcher更新,watcher取的最新值作为value,从而实现依赖更新计算属性才更新
5.对于watch:调用$watch封装成一个user watcher,如果有immediate options传入,就在封装的时候就调用一遍callback,有deep options传进来的话就将该属性的所有嵌套属性记为依赖

beforeCreate之前主要是做准备工作,将该实例的options合并整理出来,再把$那些初始话
created之前就是对options做操作,data,props设置数据劫持,methods代理在vm实例上,computed,watch封装成不同类型的watcher

vue 生命周期钩子用法以及执行顺序

参考技术A    data:

          message : "lalalala"

      ,

     beforeCreate: function ()

                console.group('beforeCreate 创建前状态===============》');

              console.log("%c%s", "color:red" , "el    : " + this.$el); //undefined

              console.log("%c%s", "color:red","data  : " + this.$data); //undefined

              console.log("%c%s", "color:red","message: " + this.message) 

        ,

       created: function ()

            console.group('created 创建完毕状态===============》');

            console.log("%c%s", "color:red","el    : " + this.$el); //undefined

              console.log("%c%s", "color:red","data  : " + this.$data); //已被初始化

              console.log("%c%s", "color:red","message: " + this.message); //已被初始化

        ,

        beforeMount: function ()

            console.group('beforeMount 挂载前状态===============》');

            console.log("%c%s", "color:red","el    : " + (this.$el)); //已被初始化

            console.log(this.$el);

              console.log("%c%s", "color:red","data  : " + this.$data); //已被初始化 

              console.log("%c%s", "color:red","message: " + this.message); //已被初始化 

        ,

        mounted: function ()

            console.group('mounted 挂载结束状态===============》');

            console.log("%c%s", "color:red","el    : " + this.$el); //已被初始化

            console.log(this.$el);   

              console.log("%c%s", "color:red","data  : " + this.$data); //已被初始化

              console.log("%c%s", "color:red","message: " + this.message); //已被初始化

        ,

        beforeUpdate: function ()

            console.group('beforeUpdate 更新前状态===============》');

            console.log("%c%s", "color:red","el    : " + this.$el);

            console.log(this.$el); 

              console.log("%c%s", "color:red","data  : " + this.$data);

              console.log("%c%s", "color:red","message: " + this.message);

        ,

        updated: function ()

            console.group('updated 更新完成状态===============》');

            console.log("%c%s", "color:red","el    : " + this.$el);

            console.log(this.$el);

              console.log("%c%s", "color:red","data  : " + this.$data);

              console.log("%c%s", "color:red","message: " + this.message);

        ,

        beforeDestroy: function ()

            console.group('beforeDestroy 销毁前状态===============》');

            console.log("%c%s", "color:red","el    : " + this.$el);

            console.log(this.$el);   

              console.log("%c%s", "color:red","data  : " + this.$data);

              console.log("%c%s", "color:red","message: " + this.message);

        ,

        destroyed: function ()

            console.group('destroyed 销毁完成状态===============》');

            console.log("%c%s", "color:red","el    : " + this.$el);

            console.log(this.$el); 

              console.log("%c%s", "color:red","data  : " + this.$data);

              console.log("%c%s", "color:red","message: " + this.message)

       

 1. beforeRouteLeave:路由组件的组件离开路由前钩子,可取消路由离开。

 2. beforeEach: 路由全局前置守卫,可用于登录验证、全局路由loading等。

 3. beforeEnter: 路由独享守卫

 4. beforeRouteEnter: 路由组件的组件进入路由前钩子。

 5. beforeResolve:路由全局解析守卫

 6. afterEach:路由全局后置钩子

 7. beforeCreate:组件生命周期,不能访问this。

 8. created:组件生命周期,可以访问this,不能访问dom。

 9. beforeMount:组件生命周期

10. deactivated: 离开缓存组件a,或者触发a的beforeDestroy和destroyed组件销毁钩子。

11. mounted:访问/操作dom。

12. activated:进入缓存组件,进入a的嵌套子组件(如果有的话)。

13. 执行beforeRouteEnter回调函数next。

以上是关于Vue源码系列之生命钩子beforeCreate&created的主要内容,如果未能解决你的问题,请参考以下文章

vue 生命周期钩子

Vue笔记(Vue生命周期 11个钩子)

Vue生命周期

vue 生命周期钩子用法以及执行顺序

Vue生命周期

Vue生命周期