组件可以访问vue实列或父组件中的数据吗?
测试:
代码中我们可以将vue实列看作一个根组件
<body>
<div id="app">
<my-cpn></my-cpn>
</div>
<template id="cpn">
<div>
<h1>{{message}}</h1>
</div>
</template>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
let cpn = {
template:"#cpn",
components:{
}
}
//根组件
const test = new Vue({
el:"#app",
data:{
message:"vue实列中的数据"
},
components:{
myCpn:cpn
}
})
</script>
</body>
运行结果:报错
运行代码后我们会发现组件是不能直接访问vue实列中的数据的,而且如果可以访问,将所有数据放在vue实列中的话,vue实列就会变得非常臃肿。
结论:组件应该有自己保存数据的地方。
组件数据的存放
组件中的数据保存在哪呢?
- 组件对象也有一个data属性(也可以有methods等属性)
- 这个data属性必须是个函数
- 函数返回一个对象,对象中保存着数据
<body>
<div id="app">
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
<template id = "cpn">
<div>
<h2>{{message}}</h2>
<h1>{{count}}</h1>
<button type="button" @click="sub">减</button>
<button type="button" @click="add">加</button>
</div>
</template>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
//定义组件
const cpn = {
template:"#cpn",
data(){
return{
message:"当前计数",
count:0
}
},
methods:{
add(){
this.count++
},
sub(){
this.count--
}
}
}
const app = new Vue({
el:"#app",
data:{
},
components:{
// 注册组件
myCpn:cpn
}
})
</script>
</body>
为什么data必须是个函数
组件最大的特性就是可复用的,所以组件可能会被多个实例同时引用。如果data值为对象,将导致多个实例共享一个对象,其中一个组件改变data属性值,其它实例也会受到影响,如果data为函数,通过return 返回对象,每次引用组件data函数就会在栈内存重新开辟一个内存空间,致使每个实例都有自己独立的对象,实例之间可以互不影响的改变data属性值。
我们可以通过js来验证
验证一:
text 代码: <script type="text/javascript">
// test 函数返回一个对象
function test(){
return {
name:"xiu",
age:21
}
}
let obj1 = test();
let obj2 = test();
let obj3 = test();
// 修改obj1的name属性的值
obj1.name = "fan"
console.log(obj1.name)
console.log(obj2.name)
console.log(obj3.name)
</script>
运行结果
fan
xiu
xiu
代码中test函数和组件的data函数一样每次都会返回一个新的对象,所以我们修改了obj1的name后obj2和obj3的name都未改变,因为它们是相互独立的。
验证二:
text 代码: <script type="text/javascript">
const obj = {
name:"xiu",
age:21
}
function test(){
return obj
}
let obj1 = test();
let obj2 = test();
let obj3 = test();
// 修改obj1的name属性的值
obj1.name = "fan"
console.log(obj1.name)
console.log(obj2.name)
console.log(obj3.name)
</script>
运行结果
fan
fan
fan
代码中test函数返回的是obj的内存地址,每个对象的内存地址都是唯一的,也就是说obj1,obj2,obj3都指向同一个对象,obj是被它们三个共享的,当改变了obj1的name,obj2,obj3的name也会同时改变。