vue静态成员初始化
在initGlobalAPI
中赋值所有的的静态方法,如Vue.set、Vue.delete、Vue.nextTick
export function initGlobalAPI (Vue: GlobalAPI) {
// config
// 不能在vue.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.
// 不能当做公共api使用
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
// 定义的set,delete,nextTick静态属性
Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick
// 2.6 explicit observable API
// 2.6 新增的响应式方法
Vue.observable = <T>(obj: T): T => {
observe(obj)
return obj
}
// 将options的原型值为空
Vue.options = Object.create(null)
// 添加'component','directive','filter' 属性
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
// 将keepalive合并到components
extend(Vue.options.components, builtInComponents)
// 注册Vue.use 用来注册插件
initUse(Vue)
// 注册Vue.mixin 实现混入
initMixin(Vue)
// 注册Vue.extend基于传入的options返回一个组件的构造函数
initExtend(Vue)
// 注册 Vue.directive vue.component vue.filter
initAssetRegisters(Vue)
}
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
initUse
export function initUse (Vue: GlobalAPI) {
Vue.use = function (plugin: Function | Object) {
// this指向vue的构造函数 installedPlugins是插件列表
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
// 把 数组中的第一个元素(plugin)去除,调用插件中的方法,传递参数
const args = toArray(arguments, 1)
args.unshift(this)
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
installedPlugins.push(plugin)
return this
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
initMixin
将mixin合并到Vue.options
里面。是全局的mixin
export function initMixin (Vue: GlobalAPI) {
Vue.mixin = function (mixin: Object) {
this.options = mergeOptions(this.options, mixin)
return this
}
}
1
2
3
4
5
6
2
3
4
5
6
initExtend
Vue.extend = function (extendOptions: Object): Function {
extendOptions = extendOptions || {}
// Vue 构造函数
const Super = this
const SuperId = Super.cid
...
// 创建一个组件构造函数,调用init方法
const Sub = function VueComponent (options) {
this._init(options)
}
// 将sub的原型链指向super,并将super上的东西合并到sub的options
Sub.prototype = Object.create(Super.prototype)
Sub.prototype.constructor = Sub
Sub.cid = cid++
// 合并options
Sub.options = mergeOptions(
Super.options,
extendOptions
)
Sub['super'] = Super
// For props and computed properties, we define the proxy getters on
// the Vue instances at extension time, on the extended prototype. This
// avoids Object.defineProperty calls for each instance created.
// 初始化子组件
if (Sub.options.props) {
initProps(Sub)
}
if (Sub.options.computed) {
initComputed(Sub)
}
// allow further extension/mixin/plugin usage
// 将vue实例中的赋值给组件
Sub.extend = Super.extend
Sub.mixin = Super.mixin
Sub.use = Super.use
// create asset registers, so extended classes
// can have their private assets too.
ASSET_TYPES.forEach(function (type) {
Sub[type] = Super[type]
})
// enable recursive self-lookup
// 把组件构造函数保存到Ctor.options.components.com = Ctor
if (name) {
Sub.options.components[name] = Sub
}
// keep a reference to the super options at extension time.
// later at instantiation we can check if Super's options have
// been updated.
Sub.superOptions = Super.options
Sub.extendOptions = extendOptions
Sub.sealedOptions = extend({}, Sub.options)
// cache constructor
// 把 组件的构造函数缓存到 options._Ctor上
cachedCtors[SuperId] = Sub
return Sub
}
}
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
initAssetRegisters
export function initAssetRegisters (Vue: GlobalAPI) {
/**
* Create asset registration methods.
*/
ASSET_TYPES.forEach(type => {
Vue[type] = function (
id: string,
definition: Function | Object
): Function | Object | void {
if (!definition) {
return this.options[type + 's'][id]
} else {
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && type === 'component') {
validateComponentName(id)
}
// Vue.component('comp', {template:''})
if (type === 'component' && isPlainObject(definition)) {
definition.name = definition.name || id
// 把组件配置转换成组件的构造函数
definition = this.options._base.extend(definition)
}
if (type === 'directive' && typeof definition === 'function') {
definition = { bind: definition, update: definition }
}
// 全局注册,存储资源并赋值
// this.options['components']['comp'] = definition
this.options[type + 's'][id] = definition
return definition
}
}
})
}
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
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