話不多說(shuō),直接看例子
<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>
我注冊(cè)了一個(gè)局部組件app-com,定義了msg為0,以及點(diǎn)擊事件,每點(diǎn)擊一次加1,并且組件復(fù)用了三次。打開(kāi)瀏覽器看一下效果,結(jié)果發(fā)現(xiàn)報(bào)錯(cuò)了

報(bào)錯(cuò)信息是data必須為一個(gè)函數(shù),然后我改成了函數(shù),代碼為
data() {
return {
msg: 0
}
},
報(bào)錯(cuò)沒(méi)了,組件也正常顯示。為什么函數(shù)就可以,而對(duì)象就不行呢?接著看下面兩個(gè)栗子
第一個(gè)栗子
function abc() {
return {
name: "肖戰(zhàn)"
}
}
let fun1 = abc()
let fun2 = abc()
let fun3 = abc()
console.log(fun1.name); //肖戰(zhàn)
console.log(fun2.name); //肖戰(zhàn)
console.log(fun3.name); //肖戰(zhàn)
如果我們改變了fun1的name,那其他兩個(gè)會(huì)變嘛?答案是不會(huì),看下圖

第二個(gè)栗子
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,那其他兩個(gè)會(huì)變嘛?答案是會(huì),看下圖

為什么呢?因?yàn)楹瘮?shù)調(diào)用了三次,被儲(chǔ)存在fun1,fun2,fun3三個(gè)不同的內(nèi)存地址中,彼此之間互不影響。
而對(duì)象呢,obj1,obj2,obj3三個(gè)的.name屬性的內(nèi)存地址都指向了obj,互相影響
而一旦你理解了這兩個(gè)栗子,自然就懂了組件的data為什么是函數(shù)。是為了復(fù)用組件時(shí),組件之間互不影響,如下面是開(kāi)頭代碼的效果圖,點(diǎn)擊了第一個(gè)button,只有1變了,而不會(huì)去影響其他的

總結(jié):組件中data值不能為對(duì)象,因?yàn)閷?duì)象是引用類型,組件可能會(huì)被多個(gè)實(shí)例同時(shí)引用。
如果data值為對(duì)象,將導(dǎo)致多個(gè)實(shí)例共享一個(gè)對(duì)象,其中一個(gè)組件改變data屬性值,其它實(shí)例也會(huì)受到影響。