Vue 全局API
书接上回,
从之前分析Vue构造函数那篇起,回溯之前调用src/core/instance/index.js
的src/core/index.js
。
现在我们打开src/core/index.js
,看到这个文件引入了如下的内容:
1
2
3
4
5
|
import Vue from './instance/index'
import { initGlobalAPI } from './global-api/index'
import { isServerRendering } from 'core/util/env'
import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
|
这部分有什么奥妙?
Vue全局API
看到这行 initGlobalAPI(Vue)
,在src/core/instance/index.js
export出来的Vue初始化了全局API。
下面对ssr的情况进行判断处理:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// core/index.js 文件中
Object.defineProperty(Vue.prototype, '$isServer', {
get: isServerRendering
})
Object.defineProperty(Vue.prototype, '$ssrContext', {
get () {
/* istanbul ignore next */
return this.$vnode && this.$vnode.ssrContext
}
})
// expose FunctionalRenderContext for ssr runtime helper installation
Object.defineProperty(Vue, 'FunctionalRenderContext', {
value: FunctionalRenderContext
})
|
同理,对SSR的$isServer
和$ssrContext
也是只读的。
最后的
1
2
|
Vue.version = '__VERSION__'
|
则是用打包工具在相应的环境替换成对应的版本号。
这里,我们主要重点关注全局API的具体实现。
打开 src/core/global-api/index.js
,这里是全局API实现的入口文件。
首先是引入配置:import config from '../config'
在src/core/global-api/
的文件夹下面,还分别有4个文件,我们可以看到index.js
的开头引入了这些文件:
1
2
3
4
|
import { initUse } from './use'
import { initMixin } from './mixin'
import { initExtend } from './extend'
import { initAssetRegisters } from './assets'
|
这部分是全局api的一些功能实现,被拆分到几个部分。
接下来,看到下面几行
1
2
3
4
5
6
7
8
9
10
11
12
|
import { set, del } from '../observer/index'
import { ASSET_TYPES } from 'shared/constants'
import builtInComponents from '../components/index'
import {
warn,
extend,
nextTick,
mergeOptions,
defineReactive
} from '../util/index'
|
这些引入的模块具体是做什么的,我们顺着下面的代码读下去应该就能知道。
在文件的20行左右,是一个函数
export function initGlobalAPI (Vue: GlobalAPI) {...}
见名知意,这个函数就是负责初始化全局API。
函数参数后的GlobalAPI
是Flow的 Interface
,用来检查和GlobalAPI相关的类型的。
下面看到函数内部的实现:
1
2
3
4
5
6
7
8
9
10
11
12
|
// 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)
|
这里的configDef,注意,是configDef。configDef
是类似这前一章分析过的那样,利用了defineProperty()
方法和存取器属性(accessor property)。在非生产环境企图修改configDef会有个警告。关于config的具体分析,笔者会在另一篇文章中详述。
下面继续向下看,
1
2
3
4
5
6
7
8
9
|
// exposed util methods.
// NOTE: these are not considered part of the public API - avoid relying on
// them unless you are aware of the risk.
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
|
这里暴露了Vue自己的一些util方法。但是注释告知了,这些方法不属于公共API,要避免依赖于这样方法。
下面是:
1
2
3
|
Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick
|
set
和 del
分别来自:
import { set, del } from '../observer/index'
。
nextTick
来自'../util/index'
。
接下来是
1
|
Vue.options = Object.create(null)
|