123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- /* @flow */
- import config from '../config'
- import { initProxy } from './proxy'
- import { initState } from './state'
- import { initRender } from './render'
- import { initEvents } from './events'
- import { mark, measure } from '../util/perf'
- import { initLifecycle, callHook } from './lifecycle'
- import { initProvide, initInjections } from './inject'
- import { extend, mergeOptions, formatComponentName } 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++
- let startTag, endTag
- /* istanbul ignore if */
- if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
- startTag = `vue-perf-start:${vm._uid}`
- endTag = `vue-perf-end:${vm._uid}`
- mark(startTag)
- }
- // 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')
- initInjections(vm) // resolve injections before data/props
- initState(vm)
- initProvide(vm) // resolve provide after data/props
- callHook(vm, 'created')
- /* istanbul ignore if */
- if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
- vm._name = formatComponentName(vm, false)
- mark(endTag)
- measure(`vue ${vm._name} init`, startTag, endTag)
- }
- if (vm.$options.el) {
- vm.$mount(vm.$options.el)
- }
- }
- }
- export function initInternalComponent (vm: Component, options: InternalComponentOptions) {
- const opts = vm.$options = Object.create(vm.constructor.options)
- // doing this because it's faster than dynamic enumeration.
- const parentVnode = options._parentVnode
- opts.parent = options.parent
- opts._parentVnode = parentVnode
- const vnodeComponentOptions = parentVnode.componentOptions
- opts.propsData = vnodeComponentOptions.propsData
- opts._parentListeners = vnodeComponentOptions.listeners
- opts._renderChildren = vnodeComponentOptions.children
- opts._componentTag = vnodeComponentOptions.tag
- 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 = resolveConstructorOptions(Ctor.super)
- const cachedSuperOptions = Ctor.superOptions
- if (superOptions !== cachedSuperOptions) {
- // super option changed,
- // need to resolve new options.
- Ctor.superOptions = superOptions
- // check if there are any late-modified/attached options (#4976)
- const modifiedOptions = resolveModifiedOptions(Ctor)
- // update base extend options
- if (modifiedOptions) {
- extend(Ctor.extendOptions, modifiedOptions)
- }
- options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)
- if (options.name) {
- options.components[options.name] = Ctor
- }
- }
- }
- return options
- }
- function resolveModifiedOptions (Ctor: Class<Component>): ?Object {
- let modified
- const latest = Ctor.options
- const sealed = Ctor.sealedOptions
- for (const key in latest) {
- if (latest[key] !== sealed[key]) {
- if (!modified) modified = {}
- modified[key] = latest[key]
- }
- }
- return modified
- }
|