在上一篇中,我们讨论了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实际上是给Vue的prototype上添加了_init方法,这样this._init()才可以调用。其他几个xxxMixin也都类似,给Vue的prototype上添加了不同的方法。
除此之外,在前面的core/index.js、runtime/index.js、web/entry-runtime-with-compiler.js中也均在原型上添加了一些方法。
其中,在core/index.js中通过initGlobalAPI(Vue)给Vue添加了全局方法。