vue
Version:
Reactive, component-oriented view layer for modern web interfaces.
89 lines (83 loc) • 2.71 kB
JavaScript
/* @flow */
import { initProxy } from './proxy'
import { initState } from './state'
import { initRender } from './render'
import { initEvents } from './events'
import { initLifecycle, callHook } from './lifecycle'
import { mergeOptions } from '../util/index'
let uid = 0
export function initMixin (Vue: Class<Component>) {
Vue.prototype._init = function (options?: Object) {
const vm: Component = this
// a uid
vm._uid = uid++
// a flag to avoid this being observed
vm._isVue = true
// merge options
if (options && options._isComponent) {
// optimize internal component instantiation
// since dynamic options merging is pretty slow, and none of the
// internal component options needs special treatment.
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
initProxy(vm)
} else {
vm._renderProxy = vm
}
// expose real self
vm._self = vm
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initState(vm)
callHook(vm, 'created')
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}
}
function initInternalComponent (vm: Component, options: InternalComponentOptions) {
const opts = vm.$options = Object.create(vm.constructor.options)
// doing this because it's faster than dynamic enumeration.
opts.parent = options.parent
opts.propsData = options.propsData
opts._parentVnode = options._parentVnode
opts._parentListeners = options._parentListeners
opts._renderChildren = options._renderChildren
opts._componentTag = options._componentTag
opts._parentElm = options._parentElm
opts._refElm = options._refElm
if (options.render) {
opts.render = options.render
opts.staticRenderFns = options.staticRenderFns
}
}
export function resolveConstructorOptions (Ctor: Class<Component>) {
let options = Ctor.options
if (Ctor.super) {
const superOptions = Ctor.super.options
const cachedSuperOptions = Ctor.superOptions
const extendOptions = Ctor.extendOptions
if (superOptions !== cachedSuperOptions) {
// super option changed
Ctor.superOptions = superOptions
extendOptions.render = options.render
extendOptions.staticRenderFns = options.staticRenderFns
extendOptions._scopeId = options._scopeId
options = Ctor.options = mergeOptions(superOptions, extendOptions)
if (options.name) {
options.components[options.name] = Ctor
}
}
}
return options
}