我们都知道,从一个new Vue开始,就说明一个Vue项目的开始:
new Vue({
el: ...,
data: ...,
....
})
那么在这次实例化的过程中,究竟发生了哪些行为呢?
Vue的源码文件,其核心代码在src/core
目录下。下面我们从入口文件index.js
开始进入:
/ src/core/index.js
// 这里是我们 Vue 核心方法
import Vue from './instance/index'
// 根据命名,应该可以猜出这里是初始化一些全局API
import { initGlobalAPI } from './global-api/index'
// 根据命名,这里应该是获取一个Boolean类型的变量,来判断是不是ssr
import { isServerRendering } from 'core/util/env'
// 这里开始执行初始化全局变量
initGlobalAPI(Vue)
// 为Vue原型定义属性$isServer
Object.defineProperty(Vue.prototype, '$isServer', {
get: isServerRendering
})
// 为Vue原型定义属性$ssrContext
Object.defineProperty(Vue.prototype, '$ssrContext', {
get () {
/* istanbul ignore next */
return this.$vnode && this.$vnode.ssrContext
}
})
Vue.version = '__VERSION__'
export default Vue
首先找到core/instance/index
文件,可以清晰的看到
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'
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
这里简单粗暴的定义了一个 Vue Class,然后又调用了一系列init、mixin
这样的方法来初始化一些功能,具体的我们后面在分析,不过通过代码我们可以确认的是这里确实是导出了一个 Vue 功能类。
接下来,我们接着看initGlobalAPI
这个东西,其实在Vue官网上,就已经为我们说明了Vue的全局属性:
// core/global-api/index
...
export function initGlobalAPI (Vue: GlobalAPI) {
// config
const configDef = {}
configDef.get = () => config
if (process.env.NODE_ENV !== 'production') {
configDef.set = () => {
warn(
'Do not replace the Vue.config object, set individual fields instead.'
)
}
}
Object.defineProperty(Vue, 'config', configDef)
// 这些工具方法不视作全局API的一部分,除非你已经意识到某些风险,否则不要去依赖他们
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
// 这里定义全局属性
Vue.se