Appearance
当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
定义一个组件Foo,data中有count,值为10,组件模板中显示count并且有一个按钮,每点一下count就会自增,在App组件中多次使用这个Foo组件,生成多个实例,如果data是对象形式,其中一个组件对count的修改会影响到另一个组件。
只有根组件,即main.js中data写对象不报错,其他组件data写对象都会报错,因为组件就是Vue构造器的子类,组件通过_init初始化,由于Vue.mixin可以混入全局data,因此也有data的合并策略,但是mergeOptions只有在option._isComponent为false时才会传第三个参数vm,也就是说只有根组件进行初始化才会传vm,合并策略中会判断vm是否为真,只有为假时才会对childVal的的类型进行判断,发现不是函数就会警告data必须是一个函数并返回不进行之后的逻辑,因此main.js中data写对象不报错,其他组件data写对象都会报错。如果我们把这个判断注释掉就会出现上面例子的情况。
javascript
strats.data = function (
parentVal,
childVal,
vm
) {
if (!vm) {
if (childVal && typeof childVal !== 'function') {
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)
};