2017-10-19 40 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

相關問題