首先我们创建一个组件
<template id="cpn">
<div>
<p>总数{{count}}</p>
<button @click="count++">+</button>
<button @click="count--">—</button>
</div>
</template>
<script>
var vm = new Vue({
el:"#app",
data:{
col:true,
currentIndex:0,
moives:['星游记','魁拔','刺客五六七']
},
components :{
'cpn' : {
template :'#cpn',
// 函数return每次都会返回一个新的对象
// 如果不是 用对象的内存地址是一样的 多个组件用同一个data 就产生严重问题
data () {
return {
count:0,
}
}
}
},
methods: {
changeA (index) {
this.currentIndex = index
}
},
mounted() {
},
})
</script>
子组件定义了一个变量 count
然后我们创建三个组件实例对象(也就是调用三次)
<div id="app">
<ul id="my-ul">
<li @click="changeA(index)" :class="{col:currentIndex===index}" v-for="(item,index) in moives">{{item}}-{{index}}</li>
</ul>
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
可以试想一下每个实例对象是否共用一个data对象,可以在页面中试一下
并不是,如果是的话,改变一个count,所以的count都会改变。
每个组件实例有属于自己data对象。
为什么讷?
因为组件的data是一个函数,每次调用的时候返回一个对象!
如何理解这句话讷
举个栗子~
<script>
const obj = {
name:"mxl",
age:18
}
function abc (){
return obj
//返回就是一个内存地址
}
function cba (){
//返回一个新的栈 ,开辟了新的空间
return{
name:"mxl",
age:18
}
}
let obj1 = abc();
//没有开辟新的空间,将obj内存地址赋给了obj1
let obj2 = abc();
let obj3 = abc();
let obj4 = cba();
//每次都会开辟一个新的栈
let obj5 = cba();
let obj6 = cba();
obj4.name = "someone"
console.log(obj5)
console.log(obj6)
obj1.name ="someone"
console.log(obj2)
console.log(obj3)
</script>
用图示来展示abc 大概就是这样
创建的obj1实际上只是指向obj的内存地址。
不管创建了多少个实例,指向的永远是相同的地址。这样就产生了很严重的问题
修改别的实例,所有的实例对象都会改变
所以vue避免了这个问题,如果写成了对象,直接就会报错~
这就是为什么vue组件的data必须是个函数的原因。