这是我参与8月更文挑战的第28天,活动详情查看: 8月更文挑战
序言
相信每一个有使用过 Vue 的朋友都对其中的 data 很熟悉,必然使用的,但是一直以来我都有一些疑惑,那就是在组件中为什么存放数据不用一个对象,而是要使用函数呢?今天我们就来一探究竟。
Vue中的data是什么
我们从官方文档得知,data的描述是:
- 类型:
Object | Function - 限制:组件的定义只接受 function
由描述可知,data 的本质是一个对象,或者一个函数,但是当data在组件中的时候,一定得是一个函数,正如我们经常写的
new Vue({
el:'#app',
data:{
varOne:1,
varTwo:2,
varThree:3
}
})
但是在组件中,定义的data必须是函数类型,例子如下
Vue.component('myComponent',{
props:[],
data:function(){
return {
varOne:1,
varTwo:2,
varThree:3
}
}
})
data的特性
- Vue实例的数据对象data,要成为响应式的,Vue会递归 data 的属性 ,转换成 getter/setter, 从而让 data的属性能够响应数据的变化,
- 因此也有一个限制,那就是,对象必须是纯粹的对象,如果是浏览器创建的原始对象,原型上的属性会被忽略,这也是考虑到性能问题作出的取舍。
- 一旦处理过,则不需要再次在data上添加响应式属性。因此最好在创建实例之前,就声明好对应的属性。
- Vue 实例创建之后,可以通过 vm.data.a`。
- 需要注意的是以*或$开头的属性不会被代理,因为他会于Vue内置的属性,API方法冲突。就是你可以在data中可以定义属性时在属性名开头加上下划线"_"或者美元符号 ,就不可以直接访问,
<body>
<div id="app">
<span> {{coolFish}}</span>
<span>{{_coolFish}}</span>
</div>
</body>
<script>
new Vue({
el:'#app',
data:{
coolFish:'boy',
_coolFish:'coolBoy'
}
})
</script>
以上会报错,因为_coolFish这种变量不能直接读取,正确的做法如下
<body>
<div id="app">
<span> {{coolFish}}</span>
<span>{{$data._coolFish}}</span>
</div>
</body>
<script>
new Vue({
el:'#app',
data:{
coolFish:'boy',
_coolFish:'coolBoy'
}
})
</script>
为什么在组件中,data是一个函数
因为如果将data设计为一个对象时,所有的组件实例都会使用data属性,任意一个组件修改了data就会影响到其他组件的data,造成数据混乱。如果定义为一个function,每个组件都会生成各自的data属性。这就就不会相互影响,解耦开了。
Vue.component('component1',{
props:[],
data: {
varOne:1,
varTwo:2,
varThree:3
}
})
Vue.component('component2',{
props:[],
data: {
varOne:1,
varTwo:2,
varThree:3
},
methods: {
this.varOne = 2
}
})
那么组件以中的varOne 也会变成2,这样就会造成混乱,利用函数的作用域的特性,可以巧妙的将其各自隔离开来,每个组件的数据各自维护 注意:data不要使用箭头函数