Vue解疑之data属性为什么是函数

Vue解疑之data属性为什么是函数

在Vue项目中,我们通常使用单文件组件和全局的component方法来定义组件,像下面这样:

Vue.component('test', {
    data () {
        return 'test'
    }
})

但是,不管是使用单文件组件或是component的函数,我们发现组件options中的data是一个函数,并且返回了一个对象,为什么我们不直接用一个对象来赋值给data呢?

我们先来看下如果直接使用对象赋值给组件的data属性会发生什么?对于这个问题,Vue官网中给出了相应的回答:

当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。

有的人或许不太明白这段话是什么意思,下面我们来看一个例子。


// Test.vue
<template>
  <div>
    {{count}}
    <button @click="add">add</button>
  </div>
</template>
<script>
  export default {
    data: {
      count: 1
    },
    methods: {
      add () {
        this.count++
      }
    }
  }
</script>

// demo.vue
<template>
  <div>
    <Test></Test>
    <Test></Test>
  </div>
</template>
<script>
export default {
  import Test from './Test.vue'
  components: {
    Test
  }
}
</script>

我们在demo文件中引入了并使用了我们定义的data是对象的Test组件,效果如下图:

Vue解疑之data属性为什么是函数_第1张图片

这时候我们点击下add按钮,会发现
Vue解疑之data属性为什么是函数_第2张图片

两个组件的count值都变成了2,这个就是因为上面所说得的两个Test组件共享了data对象,所以导致当count变化时,两个组件的data同时更新。

这个问题出现的原因主要还是由于js引用类型的特殊性所致,在Vue创建组件的时候,是直接把创建组件的options进行传入,并没有做什么特殊操作,所以每个Test组件都一直保持着对同一个data对象的引用。所以要使用一个函数来返回一个对象以保证每个组件中的data都是独立的、唯一的。

其实Vue开发者也可以在创建组件的时候对options中的data进行一个深克隆来支持data是对象这个特性,但是深克隆对性能的消耗相对较大,不如直接与使用者约定好只能使用函数来定义data。

你可能感兴趣的:(前端,Vue)