话不多说,直接看例子
<body>
<div id="app">
<app-com></app-com>
<app-com></app-com>
<app-com></app-com>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
components: {
"app-com": {
template: `<button @click = "add">{{msg}}</button>`,
data: {
msg: 0
},
methods: {
add() {
this.msg++
}
}
}
}
})
</script>
</body>
我注册了一个局部组件app-com,定义了msg为0,以及点击事件,每点击一次加1,并且组件复用了三次。打开浏览器看一下效果,结果发现报错了

报错.png
报错信息是data必须为一个函数,然后我改成了函数,代码为
data() {
return {
msg: 0
}
},
报错没了,组件也正常显示。为什么函数就可以,而对象就不行呢?接着看下面两个栗子
第一个栗子
function abc() {
return {
name: "肖战"
}
}
let fun1 = abc()
let fun2 = abc()
let fun3 = abc()
console.log(fun1.name); //肖战
console.log(fun2.name); //肖战
console.log(fun3.name); //肖战
如果我们改变了fun1的name,那其他两个会变嘛?答案是不会,看下图

1111.png
第二个栗子
let obj = {
name: '蔡徐坤'
}
function abc() {
return obj
}
let obj1 = abc()
let obj2 = abc()
let obj3 = abc()
console.log(obj1.name);
console.log(obj2.name);
console.log(obj3.name);
如果我们改变了obj1的name,那其他两个会变嘛?答案是会,看下图

2222.png
为什么呢?因为函数调用了三次,被储存在fun1,fun2,fun3三个不同的内存地址中,彼此之间互不影响。
而对象呢,obj1,obj2,obj3三个的.name属性的内存地址都指向了obj,互相影响
而一旦你理解了这两个栗子,自然就懂了组件的data为什么是函数。是为了复用组件时,组件之间互不影响,如下面是开头代码的效果图,点击了第一个button,只有1变了,而不会去影响其他的

3333.png
总结:组件中data值不能为对象,因为对象是引用类型,组件可能会被多个实例同时引用。
如果data值为对象,将导致多个实例共享一个对象,其中一个组件改变data属性值,其它实例也会受到影响。