我们刚开始定义了构造函数Vue时,给他内部的data设置了一个值,该值为对象类型,对象类型在js中称为引用数据类型,在栈中是存储着一个指向内存中该对象的堆中的地址。当我们创建一个实例对象时,要获取函数中的data,其实只是获取了那个堆中的地址,同样的,创建第二个实例对象时,获取的也是那个地址,然而该地址指向的都是同一个数据,也就是{name: ‘李四’, age: ‘55’},所以当我们改变其中一个实例对象的data.name时,其实是先顺着地址去找到内存中的那个对象,然后改变一些值,但是因为所有创建的实例都是按照地址去寻找值的,所以其中一个改变,另一个也跟着改变啦。
所以我们在使用复用型组件时,声明data属性的值时,必须要使用函数类型,因为每次创建实例对象时,他们都是获取属于他们自己的一个对象值,并且对应的堆中的地址都不相同,所以互不影响。此时的情况用图这样表示:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
/* var obj = {
name:'里斯',
age:30
} */
function box(){
return {
name:'里斯',
age:30
}
}
var a = box()
var b = box()
var c = box()
a.name = '张三'
console.log(a);
console.log(b);
console.log(c);
</script>
</body>
</html>
返回的是 new Object() 每次都是一个新的对象 指向不同的内存地址,所以
如果如下这样写:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var obj = {
name:'里斯',
age:30
}
function box(){
return obj
}
var a = box()
var b = box()
var c = box()
a.name = '张三'
console.log(a);
console.log(b);
console.log(c);
</script>
</body>
</html>
这里的a b c都指向同一个内存地址 所以一旦a.name改动 b和c也跟着变动 如图:
现在我们放到vue中
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<h2>data不使用函数</h2>
<cpn1></cpn1>
<cpn1></cpn1>
<hr>
<h2>data使用函数</h2>
<cpn2></cpn2>
<cpn2></cpn2>
<hr>
</div>
<script src="vue.js"></script>
<template id="cpn1">
<div>
<button @click="count--">-</button>
当前计数:{{count}}
<button @click="count++">+</button>
</div>
</template>
<template id="cpn2">
<div>
<button @click="count--">-</button>
当前计数:{{count}}
<button @click="count++">+</button>
</div>
</template>
<script>
const obj = {
count: 0
};
const app = new Vue({
el: "#app",
components: { //局部组件创建
cpn1: {
template: '#cpn1',
data() {
return obj;
}
},
cpn2: {
template: '#cpn2',
data() {
return {
count: 0
}
}
}
}
})
</script>
</body>
</html>
这样就可以很清楚的知道data为什么是函数了