2017-10-19 42 views
1

我读了关于Vue components,并找到他们为什么数据需要有些混乱的功能说明:为什么VUE组件数据是一个函数?

根实例

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

A组分

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 
}) 

所以我仍然留有一个问题,为什么一个组件不能有一个数据属性?

回答

6

从我的这种理解,这是为了节省内存

许多框架,如角2,(有时)反应,使一个组件单独对象的每个实例。这意味着每个组件需要的每个组件都被初始化。通常情况下,你只需要为每次初始化保留一个组件的数据。方法和这样的保持不变。

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

See this

+0

那篇文章是否澄清此事,谢谢:) – Kokodoko

+1

太棒了!当我开始学习Vue时,我也遇到了这个问题 –

1

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

1

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

此预防措施由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 
    } 
} 

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

+0

谢谢,这很有道理。我现在使用“vue-class-component”,这似乎抽象出了数据作为函数的想法。该类的所有属性都会自动转换为该函数,但您无需自己定义该属性。它看起来像'class Bla extends Vue {myproperty =“hello”}' – Kokodoko

+0

因为它是抽象的。你不能从外部改变它的数据。希望,这是有道理的。 –

+0

是的,我认为类组件使它比普通的Vue更安全,因为数据自动成为函数。 – Kokodoko

相关问题