源码解析应从入口开始,一般在 main.js 文件中可见如下代码,其实 Vue 是class,new Vue 是实例化一个类,获得vm实例(而js中的class是通过function的方式实现的)
__ 代码1 __
import Vue from 'vue'
// 实例化Vue对象
new Vue({
el: '#app',
mounted() {
console.log(this.message);
},
data: {
message: 'Hello Vue!'
}
})
__ 代码2 __
function Vue (options) { // Vue Class
if (process.env.NODE_ENV !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword');
}
// 第2步:_init是定义在vue原型上的方法,它是在initMixin的时候绑定上去的
this._init(options);
}
// 先执行这些mixin操作
initMixin(Vue); // 第1步:把_init绑定到Vue原型上
stateMixin(Vue);
eventsMixin(Vue);
lifecycleMixin(Vue);
renderMixin(Vue);
如图1所示,在init方法中共做了以下几件事:
(1)定义uid
(2)合并options,使得new Vue中的options,可通过vm.$options.el/data直接访问
(3)各种初始化(生命周期,events,render,执行beforeCreated钩子函数,injections,state,provide,执行created钩子函数)
(4)执行$mount(注意执行前后,Html页面的变化)
—图1—

总结图2内容:
(1)_init方法中 => initState => initData,取出vm.$options.data,存于vm._data以及data
(2)使用proxy(vm, '_data', key)进行取值,即proxyGetter方法:this[_data][message]。并为data内部的值用Object.definProperty进行处理(为将来的响应式做准备)
—图2—
