我们都知道,VUE的data实例必须是函数,那么有没有与之相反的情况呢?答案是肯定的,因为VUE的根实例就没有“必须是函数”这个限制。

我们需要考虑“VUE组件data对象实例” 与 “VUE的根实例”。

在源码中找答案:

src\core\instance\state.js - initData()

function initData (vm: Component) {
let data = vm.$options.data
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {}
....
}

通过源码得知:

函数每次执行都会返回全新的data对象实例

export function getData (data: Function, vm: Component): any {
// #7573 disable dep collection when invoking data getters
pushTarget()
try {
return data.call(vm, vm)
} catch (e) {
handleError(e, vm, `data()`)
return {}
} finally {
popTarget()
}
}

总结:

Vue 组件可能存在多个实例,如果使用对象的形式定义data, 则会导致它们公用一个**data对象,**那么状态变更会影响所有组件实例,这是不合理的;

采用函数的形式定义,在initData时会将其作为工厂函数返回全新的data对象,有效的避免了多个实例之间的状态污染问题;

而在Vue根实例创建过程中不存在该限制,也是因为根实例只能有一个,不需要担心这种情况