组件data定义函数与对象的区别 在我们定义好一个组件的时候,vue最终都会通过Vue.extend()构成组件实例
1 2 3 4 5 6 function  Component ( ) {     } Component.prototype.data={     count :0  } 
 
创建两个组件实例:
1 2 3 4 5 const  componentA=new  Component()const  componentB=new  Component();console .log(componentB.data.count);componentA.data.count=1 ; console .log(componentB.data.count)
 
产生这样的原因是两者共用了同一个内存地址,compoentA修改的内容,同样对componentB产生了影响
如果采用函数形式,则不会出现这种情况(函数返回的对象内存地址并不相同)
1 2 3 4 5 6 7 8 function  Component ( ) {	this .data = this .data() } Component.prototype.data = function  ( ) {     return  {    		count  : 0      } } 
 
1 2 3 4 console .log(componentB.data.count)  componentA.data.count = 1  console .log(componentB.data.count)  
 
vue组件可能有多个实例,采用函数返回一个全新data形式,使每个实例对象的数据不会受到其他实例对象数据的污染 
原理: vue初始化data的代码时,data的定义可以是函数或者对象
1 2 3 4 5 6 7 function  initData  (vm: Component )  {  let  data = vm.$options.data   data = vm._data = typeof  data === 'function'      ? getData(data, vm)     : data || {}     ... } 
 
但是组件在创建的时候,会进行选项的合并,自定义组件会进入mergeOptions进行选择合并
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Vue.prototype._init = function  (options?: Object  )  {     ...          if  (options && options._isComponent) {                            initInternalComponent(vm, options)     } else  {       vm.$options = mergeOptions(         resolveConstructorOptions(vm.constructor),         options || {},         vm       )     }     ...   } 
 
定义data会进行数据校验
这时候vm实例为undefined,进入if判断,若data类型不是function,则出现警告提示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 strats.data = function  (   parentVal: any,   childVal: any,   vm?: Component  ): ?Function   {  if  (!vm) {     if  (childVal && typeof  childVal !== "function" ) {       process.env.NODE_ENV !== "production"  &&         warn(           'The "data" option should be a function '  +             "that returns a per-instance value in component "  +             "definitions." ,           vm         );       return  parentVal;     }     return  mergeDataOrFn(parentVal, childVal);   }   return  mergeDataOrFn(parentVal, childVal, vm); }; 
 
总结: 
根实例对象data可以是对象也可以是函数(根实例是单例 ),不会产生数据污染情况 
组件实例对象data必须是函数 ,目的是为了防止多个组件实例对象之间共用一个data,产生数据污染,采用函数的形式,initData时会将其作为工厂函数返回全新data对象