initGlobalAPI(Vue)
全局api是在src/core/index.js中引入并执行的
Vue.util下定义了四个方法
warn是提示警告用的,非重点
extend方法是合并扩展对象属性,实现很简单
mergeOptions方法是合并options
defineReactive方法是定义响应式对象的,将在响应式原理章节讲解
Vue.util = {
// 提示警告
warn,
// 合并扩展对象属性
extend,
// 合并两个options的方法
mergeOptions,
// 定义响应式属性的方法
defineReactive
}
接下来又定义了Vue构造函数的三个静态方法 这三个方法的主要作用都是为了实现响应式原理,这些方法将在响应式原理章节讲解
// 静态 set方法
Vue.set = set
// 静态 delete方法
Vue.delete = del
// 静态 nexttick方法
Vue.nextTick = nextTick
Vue.observable = xxx
接下来定义了一些Vue.options上的属性
initUse(Vue)与插件机制相关,具体见Vue.use()插件机制章节
// 初始化Vue的options属性(静态属性)
Vue.options = Object.create(null)
// 初始化'components','directives','filters' 属性
ASSET_TYPES.forEach(type => {
Vue.options[type + 's'] = Object.create(null)
})
// this is used to identify the "base" constructor to extend all plain-object
// components with in Weex's multi-instance scenarios.
// _base标识Vue是所有组件的基础构造函数
Vue.options._base = Vue
// 初始化components属性,KeepAlive组件
extend(Vue.options.components, builtInComponents)
// 定义Vue.use插件方法
initUse(Vue)
// 定义Vue.minx方法
initMixin(Vue)
// 定义Vue.extend方法
initExtend(Vue)
// 定义Vue.component Vue.directive Vue.filter方法
initAssetRegisters(Vue)
initMixin方法主要定义了Vue.mixin方法,此方法的作用就是可以合并向Vue.options混入属性,也就是属性合并
initMixin (Vue: GlobalAPI) {
Vue.mixin = function (mixin: Object) {
this.options = mergeOptions(this.options, mixin)
return this
}
initExtend() 方法主要是定义了Vue.extend方法,调用此方法可以继承Vue构造函数生成一个Sub子构造函数
initExtend (Vue: GlobalAPI) {
/**
* Each instance constructor, including Vue, has a unique
* cid. This enables us to create wrapped "child
* constructors" for prototypal inheritance and cache them.
*/
Vue.cid = 0
let cid = 1
/**
* Class inheritance
* 基于Vue构建一个新的Vue对象
*/
Vue.extend = function (extendOptions: Object): Function {
// 待合并扩展的options
extendOptions = extendOptions || {}
// 保存自身实例
const Super = this
// 取得自身实例的cid
const SuperId = Super.cid
// 做了一波缓存操作,如果同一待扩展对象多次用调用同一个Vue实例的extend方法,
// 那么直接从_Ctor中获取
const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
if (cachedCtors[SuperId]) {
return cachedCtors[SuperId]
}
// 做了一波名称合法校验
const name = extendOptions.name || Super.options.name
if (process.env.NODE_ENV !== 'production' && name) {
validateComponentName(name)
}
// 定义子构造器,以下操作实现了一波原型继承
const Sub = function VueComponent (options) {
// 子构造器调用父类构造方法
this._init(options)
}
// 给子类原型赋值,这里有个问题就是constructor还是指向Super啊
Sub.prototype = Object.create(Super.prototype)
// 所以这里给重新指向了一波constructor
Sub.prototype.constructor = Sub
// cid++
Sub.cid = cid++
// 合并options
Sub.options = mergeOptions(
Super.options,
extendOptions
)
// 子类的super属性指向父类
Sub['super'] = Super
// For props and computed properties, we define the proxy getters on
// the Vue instances at extension time, on the extended prototype. This
// avoids Object.defineProperty calls for each instance created.
if (Sub.options.props) {
initProps(Sub)
}
if (Sub.options.computed) {
initComputed(Sub)
}
// allow further extension/mixin/plugin usage
Sub.extend = Super.extend
Sub.mixin = Super.mixin
Sub.use = Super.use
// create asset registers, so extended classes
// can have their private assets too.
ASSET_TYPES.forEach(function (type) {
Sub[type] = Super[type]
})
// enable recursive self-lookup
if (name) {
Sub.options.components[name] = Sub
}
// keep a reference to the super options at extension time.
// later at instantiation we can check if Super's options have
// been updated.
Sub.superOptions = Super.options
Sub.extendOptions = extendOptions
Sub.sealedOptions = extend({}, Sub.options)
// 缓存
// cache constructor
cachedCtors[SuperId] = Sub
return Sub
}
}