说明
本源码解读基于vue@2.6.10版本
入口文件
vue的入口文件在src/core/index.js,我们可以看到,在这个文件里,初始化了Vue的全局api,为Vue原型上挂载了$isServer,$ssrContext属性,为Vue挂载FunctionalRenderContext属性,然后暴漏出Vue
initGlobalAPI(Vue)
Object.defineProperty(Vue.prototype, '$isServer', {
get: isServerRendering
})
Object.defineProperty(Vue.prototype, '$ssrContext', {
get () {
/* istanbul ignore next */
return this.$vnode && this.$vnode.ssrContext
}
})
// expose FunctionalRenderContext for ssr runtime helper installation
Object.defineProperty(Vue, 'FunctionalRenderContext', {
value: FunctionalRenderContext
})
Vue.version = '__VERSION__'
export default Vue
全局api
接下来我们来分析initGlobalAPI做的事情。 首先,为Vue定义config属性,并且在生产环境中如果用户要设置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)
接下来,为Vue挂载util,set,delete,nextTick等属性或方法
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick
在vue2.6版本,也暴漏了observable这个属性给用户
Vue.observable = <T>(obj: T): T => {
observe(obj)
return obj
}
接着为Vue的options属性添加components,directives,filters选项,初始化为空对象
const ASSET_TYPES = [
'component',
'directive',
'filter'
]
Vue.options = Object.create(null)
ASSET_TYPES.forEach(type => {
Vue.options[type + 's'] = Object.create(null)
})
之后,为options添加_base选项,赋值为Vue本身,按照官方的说明,目的是在weex的多实例场景中,扩展纯对象组件时,区分组件的基类构造函数
// this is used to identify the "base" constructor to extend all plain-object
// components with in Weex's multi-instance scenarios.
Vue.options._base = Vue
最后,初始化options里的components,初始化Use,Mixin,Extend,以及AssetRegister
extend(Vue.options.components, builtInComponents)
initUse(Vue)
initMixin(Vue)
initExtend(Vue)
initAssetRegisters(Vue)
下一节,我们会先分析Vue源码src/instance下的代码,这部分是Vue的核心,再分析完这部分内容后,会继续回到initGlobalAPI深入分析