为什么vue组件数据必须是一个函数?

问题描述 投票:5回答:3

我正在阅读Vue components,并找到他们解释为什么数据需要成为一个有点令人困惑的函数:

根实例

var vm = new Vue({
  el: '#example',
  data: {
    message: 'here data is a property'
  }
})

一个组件

var vm = new Vue({
  el: '#example',
  data: function () {
     return {
       counter: 0
     }
  }
})

Vue文档通过为每个组件分配一个全局计数器变量来解释这种差异,然后他们惊讶于每个组件共享相同的数据......他们也没有解释为什么他们已经在这里使用了一个函数。

var data = { counter: 0 }

Vue.component('simple-counter', {
  template: '<div>{{ counter }}</div >',
  data: function () {
    return data  
  }
})

当然,数据现在是共享的

<simple-counter></simple-counter>
<simple-counter></simple-counter>
<simple-counter></simple-counter>

当您引用全局对象作为数据源时,组件没有自己的数据就不足为奇了。对于将数据作为属性的根Vue实例也是如此。

var mydata = { counter: 0 }

var vm1 = new Vue({
  el: '#example1',
  data: mydata
})

var vm2 = new Vue({
  el: '#example2',
  data: mydata
})

所以我仍然留下为什么组件不能拥有数据属性的问题?

vue.js vuejs2
3个回答
16
投票

根据我对此的理解,这是为了节省记忆

许多框架,例如Angular 2或(有时)React,使组件的每个实例成为一个单独的对象。这意味着每个组件所需的一切都是针对每个组件进行初始化的。通常,您实际上只需要为每次初始化保持组件的数据分开。方法等保持不变。

Vue通过使数据成为返回对象的函数来避免陷阱。这允许单独的组件具有单独的内部状态,而无需完全重新实例化整个组件。方法,计算属性定义和生命周期钩子仅创建和存储一次,并针对组件的每个实例运行。

See this


2
投票

它必须是一个函数,因为其他数据将在组件的所有实例之间共享,因为对象是通过引用调用而不是按值调用。这不仅发生在引用全局对象时,也发生在数据是对象本身时。如果data是返回对象的工厂函数,则每次挂载组件的新实例时都会从头开始创建此对象,而不是仅仅将引用传递给全局数据。


1
投票

data选项应始终是返回新对象的组件上下文中的函数。

这种预防措施是由vue完成的。因此,无论何时直接在数据选项中定义对象,vue都会捕获错误。

永远不允许组件直接改变其状态。这可以防止我们在组件没有自己的状态时弄乱并做坏事。

如果这个预防措施不是由vue做出的,那么你将有机会改变从该组件拥有的任何其他组件,这将是一个安全问题。

来自documentation的示例:

很高兴理解为什么规则存在,所以让我们作弊。

<div id="example-2">
  <simple-counter></simple-counter>
  <simple-counter></simple-counter>
  <simple-counter></simple-counter>
</div>
var data = { counter: 0 }

Vue.component('simple-counter', {
  template: '<button v-on:click="counter += 1">{{ counter }}</button>',
  // data is technically a function, so Vue won't
  // complain, but we return the same object
  // reference for each component instance
  data: function () {
    return data
  }
})

new Vue({
  el: '#example-2'
})

由于所有三个组件实例共享同一个数据对象,因此递增一个计数器会增加所有这些数据对象哎哟。让我们通过返回一个新的数据对象来解决这个问题:

data: function () {
  return {
    counter: 0
  }
}

现在我们所有的计数器都有自己的内部状态。

© www.soinside.com 2019 - 2024. All rights reserved.