vue的实例方法
在new Vue之前,将会在Vue的原型上挂载一些方法,例如vm.$set、vm.$delete、vm.$watch``vm.$on、vm.$emit、vm.$off、vm.$once、vm.$mount、vm.$forceUpdate、vm.$nextTick、vm.$destory,任何vue的实例都可调用这些方法。
在执行new Vue()之后将执行this.init()方法,进行实例初始化。在运行时版本中初始化与挂载环节都在init方法中完成。且完整的生命周期都将被初始化完成。
beforeCreate
- mergeOptions:策略模式合并不同选项
- 规则化、序列化的合并组件options。normalizeProps(child, vm); normalizeInject(child, vm); normalizeDirectives(child)
- vue实例则合并Vue的全局options以及内置组件:包括components、directives、filters
- initLifecycle(vm)
- 给实例初始化了一些属性,包括以$开头的供用户使用的外部属性,也包括以_开头的供内部使用的内部属性
vm.$parent = parent vm.$root = parent ? parent.$root : vm vm.$children = [] vm.$refs = {} vm._watcher = null vm._inactive = null vm._directInactive = false vm._isMounted = false vm._isDestroyed = false vm._isBeingDestroyed = false ```
- 给实例初始化了一些属性,包括以$开头的供用户使用的外部属性,也包括以_开头的供内部使用的内部属性
- initEvents(vm)
- 初始化事件函数initEvents实际上初始化的是父组件在模板中使用v-on或@注册的监听子组件内触发的事件。
- initRender(vm)
created
- initInjections(vm)
resolveInject把inject选项中的数据转化成键值对的形式赋给result- 然后遍历
result中的每一对键值,调用defineReactive函数将其添加当前实例上
- initState(vm) 初始化实例状态的:props、data、methods、computed、watch
- initProps:首先将
props选项规范化;其次是通过validateProp函数校验父组件传入的props数据类型是否匹配并获取到传入的值的。最后通过defineReactive将属性定义为可观测数据 - initMethods:将方法绑定到this对象上
- initDatas:将
data转换成响应式并绑定到实例vm - initComputed:
- initWatch:先遍历watch,然后为每一个属性增加createWatcher。实际是为已有的data属性中增加依赖
- initProps:首先将
- initProvide(vm) :this._provide = provide
beforeMount
获取template、定义render、staticRenderFns 函数
mount
在该阶段中所做的主要工作是创建Vue实例并用其替换el选项对应的DOM元素,同时还要开启对模板中数据(状态)的监控,当数据(状态)发生变化时通知其依赖进行视图更新。
我们将挂载阶段所做的工作分成两部分进行了分析,第一部分是将模板渲染到视图上,第二部分是开启对模板中数据(状态)的监控。两部分工作都完成以后挂载阶段才算真正的完成了。
destroy
- 首先判断当前实例的
_isBeingDestroyed属性是否为true,因为该属性标志着当前实例是否处于正在被销毁的状态,如果它为true,则直接return退出函数,防止反复执行销毁逻辑。如下:触发生命周期钩子函数beforeDestroy,该钩子函数的调用标志着当前实例正式开始销毁 - 首先,需要将当前的
Vue实例从其父级实例中删除 - 接下来就开始将自己身上的依赖追踪和事件监听移除
- 同时将实例的
VNode树设置为null - 触发生命周期钩子函数
destroyed - 调用实例的
vm.$off方法(关于该方法在后面介绍实例方法时会详细介绍),移除实例上的所有事件监听器 - 最后,再移除一些相关属性的引用,至此,当前实例算是销毁完毕