结论: Vue组件可能存在多个实例,如果使用对象实现定义data,则会导致它们公用一个data对象,那么状态变更将会影响所有组件实例,这是不合理的;采用函数形式定义,在initData时会将其作为工厂函数返回全新的data对象,有效规避多实例之间状态污染问题。而在Vue根实例创建过程中则不存在该限制,也是因为根实例只能有一个,不需要担心这种情况。 1、自定义组件
// 定义一个名为 button-counter 的新组件 Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' })2、vue源码中的initData方法
(1)如果组件中的data不是函数,是个对象,则直接使用data作为组件实例中的data, (2)Vue.component只执行了一次,那么每一次组件初始化的data都指向了同一个地方(data对象),不同组件实例都公用了同一个data对象,会造成数据污染 (3)vue源码中对于组件中的data必须是个方法,不然会报错 “组件的data必须是个函数” (4)组件中data为一个工厂函数,为了每一个组件实例相互不干扰、相互不污染
3、vue根实例的data为啥可以是对象
// 创建根实例的时候使用new 只会出现一个单例 var vm = new Vue({ data: { a: 1 } })vue源码initMixin方法: 如果是根实例,合并option走的是mergeOptions
option合并策略里面会有判断是否有vm: 如果是根实例,完全没有去对data是否是function做判断