Vue 初始化过程,也就是我们引入 vue.esm.js 的时候,vue 都做了哪些事情?主要从入口 src/platforms/web/entry-runtime-with-compiler.js 开始分析。因为这个入口打包后就是 vue.esm.js,当然只是以这个版本为例。
src/platforms/web/entry-runtime-with-compiler.js
主要将 template 转换为 render 函数
const { render, staticRenderFns } = compileToFunctions(
template,
{
outputSourceRange: process.env.NODE_ENV !== 'production',
shouldDecodeNewlines,
shouldDecodeNewlinesForHref,
delimiters: options.delimiters,
comments: options.comments,
},
this
);
引入了 src/platforms/web/runtime/index.js 中的 Vue 和 导出了 Vue
import Vue from './runtime/index';
src/platforms/web/runtime/index.js
注册平台相关的指令和组件,包括 v-model、v-show 和 transition、transition-group
// install platform runtime directives & components
extend(Vue.options.directives, platformDirectives);
extend(Vue.options.components, platformComponents);
在 Vue 的原型上注册 patch 函数
// install platform patch function
Vue.prototype.__patch__ = inBrowser ? patch : noop;
在 Vue 的原型上注册 $mount 函数,其中 mountComponent 是用来渲染 dom
Vue.prototype.$mount = function (el?: string | Element, hydrating?: boolean): Component {
el = el && inBrowser ? query(el) : undefined;
return mountComponent(this, el, hydrating);
};
引入了 src/core/index.js 中的 Vue 和 导出了 Vue
core/index.js
Vue 构造函数添加静态方法
initGlobalAPI(Vue);
引入了 src/core/instance/index.js 中的 Vue 和 导出了 Vue
import Vue from './instance/index';
src/core/global-api/index.js
通过 Object.defineProperty 给 Vue 定义了 config 静态属性
Object.defineProperty(Vue, 'config', configDef);
给 Vue 定义了 util 静态属性,包含 warn、extend、mergeOptions、defineReactive。但是此处有一些注释,提示说尽量避免调用它们,可能会发生一些意外
// 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 定义了 set、delete、nextTick 静态属性
Vue.set = set;
Vue.delete = del;
Vue.nextTick = nextTick;
给 Vue 添加 observable 静态属性,主要将一个对象设置为可响应式
Vue.observable = <T>(obj: T): T => {
observe(obj);
return obj;
};
给 Vue 添加 options 静态属性,并给其扩展 components、directives、filters
Vue.options = Object.create(null);
ASSET_TYPES.forEach((type) => {
Vue.options[type + 's'] = Object.create(null);
});
给 Vue 添加 use 静态方法,即 Vue.use(),实现插件注册
initUse(Vue);
给 Vue 添加 mixin 静态方法,即 Vue.mixin(),实现混入
initMixin(Vue);
给 Vue 添加 extend 静态方法,即 Vue.extend(),实现扩展
initExtend(Vue);
给 Vue 添加 directive、component、filter 静态方法,即 Vue.directive()、Vue.component()、Vue.filter()
initAssetRegisters(Vue);
src/core/instance/index.js
通过 function 定义 Vue 构造函数,而且必须使用 new 关键字实例化 Vue
function Vue(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);
}
给 Vue 的原型上添加 _init 方法,作用是实例的初始化
initMixin(Vue);
给 Vue 的原型上添加 $data、$props、$set、$delete、$watch 方法
stateMixin(Vue)
给 Vue 的原型上添加 $on、$once、$off、$emit 方法
eventsMixin(Vue);