Vue源码之init

1.Vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/core/instance/index.js
function Vue (options) {
if (process.env.NODE_ENV !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
this._init(options)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue

首先定义一个构造函数Vue,执行initMixinstateMixin等初始化方法;之后用户调用new Vue()就会实例化Vue且执行_init方法,下面看_init方法做了什么

2.initMixin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// src/core/instance/init.js
// 在initMixin时会给Vue的原型上添加_init方法
export function initMixin (Vue: Class<Component>) {
Vue.prototype._init = function (options?: Object) {
const vm: Component = this
// a uid
vm._uid = uid++

...

// 合并参数
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
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')

...

if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}
}

可以看到,在callHook触发beforeCreate时候并没有initState,只是初始化了基础参数,所以在beforeCreate时候无法访问到data/method/computed/watch等方法