开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第25天,点击查看活动详情
组件可以访问Vue实例的数据吗?
在我们使用组件的时候,可以直接访问到Vue实例上面的数据吗?
我们在app.vue里声明一个数据msg,值为“v我50”,然后创建一个组件,在app.vue里引入并注册使用,然后在组件里直接使用app.vue的msg数据
//app.vue
<template>
<div id="app">
<component-a></component-a>
</div>
</template>
export default {
components: {
componentA
},
name: 'App',
data () {
return {
msg:'v我50'
}
}
}
//组件A,并在组件a里引用app实例的数据
<template>
<div>
<div>组件A</div>
<div>{{msg}}</div>
</div>
</template>
这样能访问成功吗?答案是不行的,控制台会报 “属性或方法‘msg’未在实例上定义,但在渲染过程中被引用” 的错误,所以得出组件不能直接访问vue实例中的数据的结论
所以Vue组件有自己保存数据的地方,组件是一个单独功能模块的封装,也应该有属于自己的数据,自己的数据放在那里呢?组件对象也有一个data属性(也有自己的methods等属性),只是这个data属性必须是一个函数,这个函数返回一个对象,里面才是保存着数据的地方
为什么data要是一个函数
首先看看data是一个函数的例子,创建组件a,在data里都声明一个变量count,每次点击按钮的时候count+1,然后在app.vue里都引入注册,并使用2次
//
//app.vue
<template>
<div id="app">
<component-a></component-a>
<component-a></component-a>
</div>
</template>
//组件a
<template>
<div>
<div>{{count}}</div>
<button @click="count++">+1</button>
</div>
</template>
可以看到很正常,没有什么bug,控制台也没有报错
然后再试试将data改为一个对象:
data:{
count:0
}
可以只看到控制套给我们报了一个错,告诉我们data必须是一个函数,而且连渲染都渲染不出来
我们可以欺骗一下vue让它以为是一个函数,其实本质上还是一个对象
const data={
count:0
}
export default {
data(){
return data
}
}
重新运行之后发现控制台不报错了,数据也渲染出来了,但是当增加的时候,不止当前点击的组件的count会增加,其他组件也会增加
这是为什么呢?这是因为如果2个组件用的data都是同一个对象,也就是2个数组操作的都是同一个对象,它们的内存地址是相同的,当改变组件里某一个数据的时候其他组件也会做出改变。当data是一个函数时,使用多次同样的组件会在函数的栈空间里创建一个新的对象并返回,它们的内存地址是完全不同的
相当于每个组件实例都有自己的作用域,那么局部作用域中的数据改变是不会影响其他作用域的,也就是说每个组件相互独立,互不影响