菜鸟初探Vue源码(二)-- 从入口开始

496 阅读1分钟

在上一篇中,我们讨论了Vue.js的构建过程,在web应用下,我们主要分析Runtime+Compiler版本的Vue.js,它的入口是src/platforms/web/entry-runtime-with-compiler.js。 打开入口,我们可以看到最后一行代码:

import Vue from './runtime/index'
//...此处省略多行代码
const mount = Vue.prototype.$mount
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  //...此处省略多行代码
  return mount.call(this, el, hydrating)
}
//...此处省略多行代码
export default Vue;

再打开runtime/index.js

import Vue from 'core/index'
//...此处省略多行代码
Vue.prototype.__patch__ = inBrowser ? patch : noop
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && inBrowser ? query(el) : undefined
  return mountComponent(this, el, hydrating)
}
//...此处省略多行代码
export default Vue;

再打开core/index.js

import Vue from './instance/index'
import { initGlobalAPI } from './global-api/index'
//...此处省略多行代码
initGlobalAPI(Vue)
//...此处省略多行代码
export default Vue;

最终我们找到instance/index.js,该文件定义了一个Vue函数,传入参数options

function Vue (options) {
  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()时,实际上是执行了Vue函数,函数内判断如果不是通过new的方式调用,则抛出警告。继续往下看执行了五个xxxMixin(Vue)方法,这些方法做了什么呢?以initMixin为例:

export function initMixin (Vue: Class<Component>) {
  Vue.prototype._init = function (options?: Object) {
    //...此处省略多行代码
  }
}

很明显initMixin实际上是给Vueprototype上添加了_init方法,这样this._init()才可以调用。其他几个xxxMixin也都类似,给Vueprototype上添加了不同的方法。

除此之外,在前面的core/index.jsruntime/index.jsweb/entry-runtime-with-compiler.js中也均在原型上添加了一些方法。

其中,在core/index.js中通过initGlobalAPI(Vue)Vue添加了全局方法。