1 |
|
2 |
|
3 | import config from '../config'
|
4 | import { initProxy } from './proxy'
|
5 | import { initState } from './state'
|
6 | import { initRender } from './render'
|
7 | import { initEvents } from './events'
|
8 | import { mark, measure } from '../util/perf'
|
9 | import { initLifecycle, callHook } from './lifecycle'
|
10 | import { initProvide, initInjections } from './inject'
|
11 | import { extend, mergeOptions, formatComponentName } from '../util/index'
|
12 |
|
13 | let uid = 0
|
14 |
|
15 | export function initMixin (Vue: Class<Component>) {
|
16 | Vue.prototype._init = function (options?: Object) {
|
17 | const vm: Component = this
|
18 |
|
19 | vm._uid = uid++
|
20 |
|
21 | let startTag, endTag
|
22 |
|
23 | if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
|
24 | startTag = `vue-perf-start:${vm._uid}`
|
25 | endTag = `vue-perf-end:${vm._uid}`
|
26 | mark(startTag)
|
27 | }
|
28 |
|
29 |
|
30 | vm._isVue = true
|
31 |
|
32 | if (options && options._isComponent) {
|
33 |
|
34 |
|
35 |
|
36 | initInternalComponent(vm, options)
|
37 | } else {
|
38 | vm.$options = mergeOptions(
|
39 | resolveConstructorOptions(vm.constructor),
|
40 | options || {},
|
41 | vm
|
42 | )
|
43 | }
|
44 |
|
45 | if (process.env.NODE_ENV !== 'production') {
|
46 | initProxy(vm)
|
47 | } else {
|
48 | vm._renderProxy = vm
|
49 | }
|
50 |
|
51 | vm._self = vm
|
52 | initLifecycle(vm)
|
53 | initEvents(vm)
|
54 | initRender(vm)
|
55 | callHook(vm, 'beforeCreate')
|
56 | initInjections(vm)
|
57 | initState(vm)
|
58 | initProvide(vm)
|
59 | callHook(vm, 'created')
|
60 |
|
61 |
|
62 | if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
|
63 | vm._name = formatComponentName(vm, false)
|
64 | mark(endTag)
|
65 | measure(`vue ${vm._name} init`, startTag, endTag)
|
66 | }
|
67 |
|
68 | if (vm.$options.el) {
|
69 | vm.$mount(vm.$options.el)
|
70 | }
|
71 | }
|
72 | }
|
73 |
|
74 | export function initInternalComponent (vm: Component, options: InternalComponentOptions) {
|
75 | const opts = vm.$options = Object.create(vm.constructor.options)
|
76 |
|
77 | const parentVnode = options._parentVnode
|
78 | opts.parent = options.parent
|
79 | opts._parentVnode = parentVnode
|
80 |
|
81 | const vnodeComponentOptions = parentVnode.componentOptions
|
82 | opts.propsData = vnodeComponentOptions.propsData
|
83 | opts._parentListeners = vnodeComponentOptions.listeners
|
84 | opts._renderChildren = vnodeComponentOptions.children
|
85 | opts._componentTag = vnodeComponentOptions.tag
|
86 |
|
87 | if (options.render) {
|
88 | opts.render = options.render
|
89 | opts.staticRenderFns = options.staticRenderFns
|
90 | }
|
91 | }
|
92 |
|
93 | export function resolveConstructorOptions (Ctor: Class<Component>) {
|
94 | let options = Ctor.options
|
95 | if (Ctor.super) {
|
96 | const superOptions = resolveConstructorOptions(Ctor.super)
|
97 | const cachedSuperOptions = Ctor.superOptions
|
98 | if (superOptions !== cachedSuperOptions) {
|
99 |
|
100 |
|
101 | Ctor.superOptions = superOptions
|
102 |
|
103 | const modifiedOptions = resolveModifiedOptions(Ctor)
|
104 |
|
105 | if (modifiedOptions) {
|
106 | extend(Ctor.extendOptions, modifiedOptions)
|
107 | }
|
108 | options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions)
|
109 | if (options.name) {
|
110 | options.components[options.name] = Ctor
|
111 | }
|
112 | }
|
113 | }
|
114 | return options
|
115 | }
|
116 |
|
117 | function resolveModifiedOptions (Ctor: Class<Component>): ?Object {
|
118 | let modified
|
119 | const latest = Ctor.options
|
120 | const sealed = Ctor.sealedOptions
|
121 | for (const key in latest) {
|
122 | if (latest[key] !== sealed[key]) {
|
123 | if (!modified) modified = {}
|
124 | modified[key] = latest[key]
|
125 | }
|
126 | }
|
127 | return modified
|
128 | }
|