我们都知道,VUE的data实例必须是函数,那么有没有与之相反的情况呢?答案是肯定的,因为VUE的根实例就没有“必须是函数”这个限制。
我们需要考虑“VUE组件data对象实例” 与 “VUE的根实例”。
在源码中找答案:
srccoreinstancestate.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根实例创建过程中不存在该限制,也是因为根实例只能有一个,不需要担心这种情况