您现在的位置是:首页 >技术交流 >vue2实例初始化流程网站首页技术交流

vue2实例初始化流程

Neo 丶 2024-07-09 10:33:21
简介vue2实例初始化流程

一、静态成员初始化

initGlobalApi

1.通过 Object.defineProperty(Vue, 'config', configDef) 初始化了Vue.config这个静态属性

2.定义了Vue.util,并挂载了一部分API(warn/extend/mergeOptions/defineReactive

3.定义三个静态方法(set/delete/nextTick

4.定义observable方法,内部调用observe,让入参对象变成一个响应式对象,并返回这个响应式对象

5.初始化了Vue.options对象,其__proto__指向null,在其上扩展了三个方法(component/directive/filter)

6.利用Vue.options._base暂存Vue构造函数

7.调用 extend(Vue.options.components, builtInComponents)方法,将内建组件下的全部组件都拷贝给Vue.options.components(extend实现了两个对象属性的浅拷贝)

initUse

8.调用 initUse(Vue) 注册vue.use方法,用于插件注册

initMixin

9.调用 initMixin(Vue) 注册Vue.mixin方法,用于全局混入

initExtend

10.调用 initExtend(Vue) 注册Vue.extend,基于传入的options返回一个组件的构造函数

initAssetRegisters

11.调用 initAssetRegisters(Vue) 注册Vue.directive,Vue.component和Vue.filter三个静态方法

二、实例成员初始化

实例成员初始化发生在Vue构造函数定义后,主要通过initMixinstateMixineventsMixinlifecycleMixin 以及 renderMixin 初始化Vue的实例成员

initMixin

初始化 _init 方法,也就是初始化整个Vue的入口

stateMixin

初始化 $data 和 $props 实例成员,指向实例的_data和_props,并禁止修改,只能获取

初始化实例上的 $set 和 $delete 方法,和静态成功set、delete一样

初始化 $watch,用于创建userWatcher并返回取消监听的方法

eventsMixin

初始化$on$off$destory$forceUpdate,其中 $forceUpdate 用于执行当前实例渲染 $watcher 的update方法立即更新

renderMixin

挂载渲染相关辅助函数

挂载 $nextTick,和静态成员 nextTick 是一个方法

挂载 _render,用于调用用户传入的render方法,创建虚拟DOM

runtime/index

在初始化构造函数后,经过上面所有操作初始化实例成员,随后调用 initGloabalApi 完成静态成员的初始化

最后在 runtime/index 中初始化实例的__patch__和 $mount 方法

到上一步为止,Vue的实例成员初始化完成

不过在 runtime/index 中的$mount,只是基础版本,如果是编译器版本,那么将会在 entry-runtime-with-compiler/index 中重写 $mount

三、执行vue构造函数

当vue实例成员初始化完成后,也就开始执行构造函数了,也就是最终 的new Vue(options)

其实也就是执行 this._init(options),_init方法在 core/instance/index 中调用initMixin中初始化

1.构建vm,指向当前实例(后续全部用vm代替)

2.设置实例唯一_uid,是一个自增长变量

3.添加_isVue标识,后续遇到此标识,不对vm实例对象做响应式处理

4.如果是组件初始化则执行 initInternalComponent,非组件初始化则合并静态options与实例$options

5.Vue初始化直接走合并options逻辑即可

6.开发环境执行 initProxy,生产环境直接将vm赋值给 vm._renderProxy

7.将vm实例赋值给vm._self

8.调用lifecycle(初始化 $parents/$children/$root/$refs

  • 注意:这里只知道父级是谁,以及当前初始化的实例对象是谁的子级,但是当前实例对象还没有和自己的子级形成父子关系,需要等到子级的实例对象初始化时,才会形成父子关系

9.调用initEvents

10.调用initRender

11.触发beforeCreate

12.调用initInjections

13.调用initState

14.调用initProvide

15.触发created

16.如果options上存在el,则直接调用$mount执行组件挂载,Vue构造函数初始化时存在el,立即挂载根节点

17.至此,Vue构造函数初始化完成

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。