Vue 初始化过程,也就是我们引入 vue.esm.js 的时候,vue 都做了哪些事情?主要从入口 src/platforms/web/entry-runtime-with-compiler.js 开始分析。因为这个入口打包后就是 vue.esm.js,当然只是以这个版本为例。

src/platforms/web/entry-runtime-with-compiler.js

  1. 主要将 template 转换为 render 函数

    1. const { render, staticRenderFns } = compileToFunctions(
    2. template,
    3. {
    4. outputSourceRange: process.env.NODE_ENV !== 'production',
    5. shouldDecodeNewlines,
    6. shouldDecodeNewlinesForHref,
    7. delimiters: options.delimiters,
    8. comments: options.comments,
    9. },
    10. this
    11. );
  2. 引入了 src/platforms/web/runtime/index.js 中的 Vue 和 导出了 Vue

    1. import Vue from './runtime/index';

src/platforms/web/runtime/index.js

  1. 注册平台相关的指令和组件,包括 v-model、v-show transition、transition-group

    1. // install platform runtime directives & components
    2. extend(Vue.options.directives, platformDirectives);
    3. extend(Vue.options.components, platformComponents);
  2. Vue 的原型上注册 patch 函数

    1. // install platform patch function
    2. Vue.prototype.__patch__ = inBrowser ? patch : noop;
  3. Vue 的原型上注册 $mount 函数,其中 mountComponent 是用来渲染 dom

    1. Vue.prototype.$mount = function (el?: string | Element, hydrating?: boolean): Component {
    2. el = el && inBrowser ? query(el) : undefined;
    3. return mountComponent(this, el, hydrating);
    4. };
  4. 引入了 src/core/index.js 中的 Vue 和 导出了 Vue

core/index.js

  1. Vue 构造函数添加静态方法

    1. initGlobalAPI(Vue);
  2. 引入了 src/core/instance/index.js 中的 Vue 和 导出了 Vue

    1. import Vue from './instance/index';

src/core/global-api/index.js

  1. 通过 Object.defineProperty Vue 定义了 config 静态属性

    1. Object.defineProperty(Vue, 'config', configDef);
  2. Vue 定义了 util 静态属性,包含 warnextendmergeOptionsdefineReactive。但是此处有一些注释,提示说尽量避免调用它们,可能会发生一些意外

    1. // exposed util methods.
    2. // NOTE: these are not considered part of the public API - avoid relying on
    3. // them unless you are aware of the risk.
    4. Vue.util = {
    5. warn,
    6. extend,
    7. mergeOptions,
    8. defineReactive,
    9. };
  3. Vue 定义了 set、delete、nextTick 静态属性

    1. Vue.set = set;
    2. Vue.delete = del;
    3. Vue.nextTick = nextTick;
  4. Vue 添加 observable 静态属性,主要将一个对象设置为可响应式

    1. Vue.observable = <T>(obj: T): T => {
    2. observe(obj);
    3. return obj;
    4. };
  5. Vue 添加 options 静态属性,并给其扩展 components、directives、filters

    1. Vue.options = Object.create(null);
    2. ASSET_TYPES.forEach((type) => {
    3. Vue.options[type + 's'] = Object.create(null);
    4. });
  6. Vue 添加 use 静态方法,即 Vue.use(),实现插件注册

    1. initUse(Vue);
  7. Vue 添加 mixin 静态方法,即 Vue.mixin(),实现混入

    1. initMixin(Vue);
  8. Vue 添加 extend 静态方法,即 Vue.extend(),实现扩展

    1. initExtend(Vue);
  9. Vue 添加 directive、component、filter 静态方法,即 Vue.directive()、Vue.component()、Vue.filter()

    1. initAssetRegisters(Vue);

src/core/instance/index.js

  1. 通过 function 定义 Vue 构造函数,而且必须使用 new 关键字实例化 Vue

    1. function Vue(options) {
    2. if (process.env.NODE_ENV !== 'production' && !(this instanceof Vue)) {
    3. warn('Vue is a constructor and should be called with the `new` keyword');
    4. }
    5. this._init(options);
    6. }
  2. Vue 的原型上添加 _init 方法,作用是实例的初始化

    1. initMixin(Vue);
  3. Vue 的原型上添加 $data、$props、$set、$delete、$watch 方法

    1. stateMixin(Vue)
  4. Vue 的原型上添加 $on、$once、$off、$emit 方法

    1. eventsMixin(Vue);