Vue 构造器
Vue 的本质是一个构造器
// Vue 构造函数
function Vue(options) {
// 保证了无法直接通过 Vue() 去调用,只能通过 new 的方式去创建实例
if (!(this instanceof Vue)) {
warn('Vue is a constructor and should be called with the `new` keyword');
}
this._init(options);
}
return Vue;
定义静态属性方法
在 initGlobalAPI 中定义全局 api 方法
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)
// exposed util methods.
// NOTE: these are not considered part of the public API - avoid relying on
// them unless you are aware of the risk.
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick
// 2.6 explicit observable API
Vue.observable = <T>(obj: T): T => {
observe(obj)
return obj
}
// 原型上创建了一个指向为空对象的options属性
Vue.options = Object.create(null)
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.
Vue.options._base = Vue
extend(Vue.options.components, builtInComponents)
initUse(Vue)
initMixin(Vue)
initExtend(Vue)
initAssetRegisters(Vue)
}
extend 方法实现对象的合并
function extend (to, _from) {
for (var key in _from) {
to[key] = _from[key];
}
return to
}
initMixin 流程
export function initMixin (Vue) {
Vue.prototype._init = function (options) {
const vm = this
// 1. 合并配置
if (options && options._isComponent) {
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
// 2.render代理
if (process.env.NODE_ENV !== 'production') {
initProxy(vm)
} else {
vm._renderProxy = vm
}
// 3.初始化生命周期、初始化事件中心、初始化inject,
// 初始化state、初始化provide、调用生命周期
vm._self = vm
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm)
initState(vm)
initProvide(vm)
callHook(vm, 'created')
// 4.挂载
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}
}