vue源码(一) – 初始化

vue项目的起源,始于一次Vue的实例化:

1
2
3
4
5
new Vue({
el: ...,
data: ...,
...,
})

在实例化过程中,vue本身做了哪些事情呢?打开Vue的源码文件,其核心代码在src/core目录下。从入口文件index.js开始进入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22


// Vue的核心方法
import Vue from './intance/index'
// 初始化一些全局API
import { initGlobalAPI } from './global-api/index'
// 判断是不是srr的变量
import { isServerRendering } from 'core/util/env'

// 执行初始化全局变量
initGlobalAPI(Vue)
// 为Vue原型定义属性$isServer
Object.defineProperty(Vue.prototype, '$isServer', {
get () {
/* istanbul ignore next */
return this.$vnode && this.$vnode.ssrContext
}
})

Vue.version = '__VERSION__'

export default Vue

找到core/instance/index文件,可以看到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '../util/index'

function (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)
eventMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue

这里简单的定义了一个Vue class,然后又调用一系列的init, mixin这样的方法来初始化一些功能,并且在最后导出一个Vue的功能类。

接下来,看看initGlobalAPI这个方法,在vue官网上,就已经说明了Vue的全局属性:
globalAPI.jpg
现在我们看看globalAPI的源码:

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
// core/global-api/index

...
export function initGlobalAPI (vue: GlobalAPI) {
//config
const configDef = {}
configDef.get = () => config
if (process.env.NODE_ENV !== 'production') {
configDef.set = () => {
warn(
'Do not replace thi Vue.config object, set individual fields instead.'
)
}
}
Object.defineProperty(Vue, 'config', configDef)

// 这些工具方法不视作全局API的一部分,除非你已经意识到某些风险,否则不要去依赖他们
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
// 定义全局属性
Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick

Vue.options = Object.create(null)
ASSET_TYPES.forEach(type => {
Vue.options[type + 's'] = Object.create(null)
})
Vue.options._base = Vue
extend(Vue.options.components, buildInComponents)

// 定义全局方法
initUse(Vue)
initMixin(Vue)
initExtend(Vue)
initAssetRegisters(Vue)
}

  • 【Vue.config】 各种全局配置项
  • 【Vue.util】 各种工具函数,还有一些兼容性的标志位
  • 【Vue.set/delete】 文档中有提到
  • 【Vue.nextTick】
  • 【Vue.options】 这个是options和用来构造实例的options。是Vue默认提供的资源
  • 【Vue.use】 定义initUse方法
  • 【Vue.mixin】 定义initMixin方法
  • 【Vue.extend】 邓毅initExtend方法

接下来是提供给ssr使用的全局变量$isServer$ssrContext。关于他们的使用,其实ssr文档有说明:Head管理

这便是Vue文件的入口,之后了解下Vue class的具体实现,其中会了解到Vue的相关生命周期的知识。