newVue({el:'#app',data:{message:'HelloWorld!',},})这是我使用Vue写的第一段代码,我会好奇,运行这段代码的时候,Vue背后到底做了什么?阅读和理解源代码可以让我们看到隐藏在框架背后的齿轮部件。当需要进行性能优化或遇到排查错误时,可能更容易解决问题。刚开始学习编程时,通常会寻找程序运行的入口点。在src/core/instance/index.js中可以看到vue的定义,这也是我们要找的入口。协议在先,文中只摘录了部分源码。建议大家看完之后,按照文章思路顺序阅读源码。所有源码均基于Vue@2.16.10版本。在引用的代码之前,会用注释来标记这段代码来自哪个文件。//文件:src/core/instance/index.jsfunctionVue(options){//..this._init(options);}//..initMixin(Vue);stateMixin(Vue);其实在HelloWorld项目中调用Vue构造函数的时候,最终会调用initState()//file:src/core/instance/init.jsimport{initState}from'./state'exportfunctioninitMixin(Vue:Class){Vue.prototype._init=function(options?:Object){//..initState(vm)//..}}//文件:src/core/instance/state.jsexportfunctioninitState(vm:Component){//..if(opts.props)initProps(vm,opts.props)if(opts.methods)initMethods(vm,opts.methods)//数据处理if(opts.data){initData(vm)}else{observe(vm._data={},true)}if(opts.computed)initComputed(vm,opts.computed)if(opts.watch&&opts.watch!==nativeWatch){initWatch(vm,opts.watch)}}processDatadata在initState中可以看到开发过程中经常遇到的props/data/computed的处理函数。我们来看一下数据的处理过程——initData()。//文件:src/core/instance/state.jsfunctioninitData(vm:Component){//..observe(data);//最后使用observe函数处理数据}在observe函数中查看value,即数据处理//file:src/core/observer/index.jsexportfunctionobserve(value:any,asRootData:?布尔值):观察者|void{//..让ob:观察者|voidif(hasOwn(value,'__ob__')&&value.__ob__instanceofObserver){ob=value.__ob__}elseif(shouldObserve&&!isServerRendering()&&(Array.isArray(value)||isPlainObject(value))&&Object.isExtensible(value)&&!value._isVue){//参数值将是定义的数据对象ob=newObserver(value)}//..returnob}最重要的是创建一个Observer对象,我们来看看Observer对象的结构Process//file:src/core/observer/index.jsexportclassObserver{//..constructor(value:any){this.value=valuethis.dep=newDep()//稍后会用到//。.def(value,'__ob__',this)if(Array.isArray(value)){//..this.observeArray(value)}else{//因为当前定义的数据是对象,所以会执行walk函数this.walk(value)}}walk(obj:Object){constkeys=Object.keys(obj)for(leti=0;i){for(leti=0,l=items.length;i