new Vue()被调用时发生了什么

_init方法的定义
_init方法的内部原理
callHook函数的内部于原理

new vue()被调用时,会首先进行一些初始化操作,然后进入模版编译阶段,然后进入挂载阶段。

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '../util/index'
/*Github:https://github.com/answershuto*/
function Vue (options) { //vue 函数
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  /*初始化*/
  this._init(options) //调用了这个函数 这个函数是定在原型上的 
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue

首先进行安全检查,在非生产环境下,如果没有用new来调用vue,则会在控制台报出警告。
调用this._init(options) 来执行初始化流程,
1、_Init方法的定义
通过initMixin方法将_init挂载到Vue构造函数的原型上,import { initMixin } from ‘./init’ (代码如上)

2、_init 方法的内部原理

export function initMixin (Vue: Class<Component>) {
  Vue.prototype._init = function (options) {
    vm.$options = mergeOptions(
       resolveConstructorOptions(vm.constructor),
       options || {},
       vm
     )
    initLifecycle(vm)
    initEvents(vm)
    initRender(vm)
    callHook(vm, 'beforeCreate')
    initInjections(vm) // resolve injections before data/props
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, 'created')
 	// 如果用户在实例化时传递了el,则自动开启模版编译阶段和挂载阶段
 	// 如果没有el,则不进入下一个生命周期流程
 	// 用户需要执行$mount方法,手动开启模版编译与挂载阶段
    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
  }
}

vuejs会在初始化流程的不同时期通过callhook函数触发生命周期钩子。
resolveConstructorOptions 函数的作用:获取当前实例中构造函数的options选项及其所有父级的构造函数的options。

3、callHook函数的内部于原理
作用:触发用户设置的生命周期钩子。

beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed
activated
deactivated
errorCaptured

值得注意的是:vuejs在合并options的过程中会找出options中所有key是钩子函数的名字,并将它转换成数组.

Q:为什么要转换成数组?
A:vue.minixin方法会将选项写入vue.options中,因此护i影响之后创建的所有vuejs实例,会发生一个现象:vue.mixin和用户在实例化vuejs时,如果设置了同一个生命周期钩子,在触发生命周期时,要同时触发这两个函数。转换成数组后,可以在同一个生命周期钩子列表中保存多个声明周期钩子。

实现:只需要从vm.$options中获取生命周期钩子列表,遍历列表,执行每一个生命周期钩子,触发。

function callHook (vm, hook) {		// vuejs实例的this, 声明周期钩子的名称
  var handlers = vm.$options[hook];
  if (handlers) {
    for (var i = 0, j = handlers.length; i < j; i++) {
      try {
        handlers[i].call(vm);
      } catch (e) {
        handleError(e, vm, (hook + " hook"));
      }
    }
  }
}

使用try…catch 捕获钩子函数内发生的错误,并使用handleError处理错误,handleError会依次执行父组件的errorCaptured钩子函数与全局的config.errorHandler,这也是为什么生命周期钩子errorCaptured可以捕获子孙组件的错误。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值