学习代码仓库

# 初始化Vue流程

入口

./core/instance/index.js 定义了一个构造函数

然后执行了以下方法,给构造函数的原型加了一些属性和方法

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
1
2
3
4
5

# 初始化原型(实例)的方法和属性

initMixin方法给原型增加了_init方法,也就是每次执行new Vew()的时候都会调用。具体的后面再说。// TODO

stateMixin给原型挂载了$data$props属性,并重写了它们的getter,分别读取实例的_data_props。 然后挂载了$set$del$watch方法,这些后面再细看。 // TODO

eventMixin给原型挂载了$on$once$off$emit方法,后续细看。// TODO

lifecycleMixin 方法给原型定义了_update方法、以及$forceUpdate$destroy, 后续细看 // TODO

renderMixin方法给原型定义了$nextTick方法,并且执行了installRenderHelpers方法给原型增加了一系列私有的方法,和_render方法,后续细看 //TODO

最后抛出Vue构造函数

# 初始化全局api

然后执行initGlobalApi(Vue)方法,将一些方法和属性挂在构造函数上成为全局api 如:

  • Vue.config(全局配置 文档)
  • Vue.util(暴露出来的方法,但不是作为全局api考虑的,不建议使用)
  • Vue.set 文档
  • Vue.delete 文档
  • Vue.nextTick 文档

然后初始化options Vue.options = Object.create(null)

Vue.options.componentsVue.options.directivesVue.options.filters 都为一个空对象( Object.create(null))

将这个状态的构造函数保存到Vue.options._base 然后执行 extend(Vue.options.components, builtInComponents)

builtInComponents返回的是一个对象

export default {
  name: 'keep-alive',
  abstract: true,

  props: {
    include: patternTypes,
    exclude: patternTypes,
    max: [String, Number]
  },

  created () {
    this.cache = Object.create(null)
    this.keys = []
  },

  destroyed () {
    for (const key in this.cache) {
      pruneCacheEntry(this.cache, key, this.keys)
    }
  },

  watch: {
    include (val: string | RegExp | Array<string>) {
      pruneCache(this, name => matches(val, name))
    },
    exclude (val: string | RegExp | Array<string>) {
      pruneCache(this, name => !matches(val, name))
    }
  },

  render () {
    // 后面再细看
  }
}
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

因为Vue.options.components之前是初始化的一个空对象,所以extend处理之后,现在它变成了上述代码

然后顺序调用

然后给Vue.prototype增加了$isServer$ssrContext 两个字段 最后Vue增加了version字段

所以在还未进行任何操作,只是引入了Vue时,Vue的状态如下

# 知识点

Object.defineProperty