Vue中的data是什么

5,590 阅读2分钟

这是我参与8月更文挑战的第28天,活动详情查看:              8月更文挑战

序言

相信每一个有使用过 Vue 的朋友都对其中的 data 很熟悉,必然使用的,但是一直以来我都有一些疑惑,那就是在组件中为什么存放数据不用一个对象,而是要使用函数呢?今天我们就来一探究竟。

Vue中的data是什么

我们从官方文档得知,data的描述是:

  1. 类型: Object | Function
  2. 限制:组件的定义只接受 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的特性

  1. Vue实例的数据对象data,要成为响应式的,Vue会递归 data 的属性 ,转换成 getter/setter, 从而让 data的属性能够响应数据的变化,
  2. 因此也有一个限制,那就是,对象必须是纯粹的对象,如果是浏览器创建的原始对象,原型上的属性会被忽略,这也是考虑到性能问题作出的取舍。
  3. 一旦处理过,则不需要再次在data上添加响应式属性。因此最好在创建实例之前,就声明好对应的属性。
  4. Vue 实例创建之后,可以通过 vm.data访问原始数据对象,Vue实例上也代理了data对象上的所有属性,因此访问vm.a等于访问vm.data 访问原始数据对象,Vue 实例上也代理了data 对象上的所有属性,因此访问 `vm.a` 等于访问 `vm.data.a`。
  5. 需要注意的是以*或$开头的属性不会被代理,因为他会于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不要使用箭头函数