2017-01-23 60 views
2

我對Vue Framework很新。我試圖將變化從父項傳播到子項,無論何時添加或刪除屬性,或稍後在組件外部更新。在下面的代碼片段中,我試圖編寫一個組件,它顯示基於從父節點傳遞給屬性的節點的名稱屬性的問候消息。vue JS不會將更改從父級傳播到組件

如果節點在初始化時包含屬性「name」(在下面的代碼片段中進行了評論),那麼一切正常。但是,如果name屬性被添加到執行的後續階段(這裏是爲了演示目的,我添加了一個設置超時並應用)。該組件拋出錯誤,並且不會反映更改。我不確定如何傳播基於組件外部其他事件生成的組件中動態屬性的更改。

基本上我想根據傳遞給它的屬性以動態方式更新顯示基於服務器響應的不同類型的小部件的組件。每當屬性得到更新時,我都希望組件自動更新。爲什麼雙向綁定在Vuejs中無法正常工作?

Vue.component('greeting', { 
 
    template: '#treeContainer', 
 
    props: {'message':Object}, 
 
    watch:{ 
 
     'message': { 
 
      handler: function(val) { 
 
       console.log('###### changed'); 
 
      }, 
 
      deep: true 
 
     } 
 
    } 
 
}); 
 

 
var data = { 
 
    note: 'My Tree', 
 
    // name:"Hello World", 
 
    children: [ 
 
     { name: 'hello' }, 
 
     { name: 'wat' } 
 
    ] 
 
} 
 

 
function delayedUpdate() { 
 
    data.name='Changed World'; 
 
    console.log(JSON.stringify(data)); 
 
} 
 

 
var vm = new Vue({ 
 
    el: '#app', 
 
    data:{ 
 
     msg:data 
 
    }, 
 
    method:{ } 
 
}); 
 

 
setTimeout(function(){ delayedUpdate() ;}, 1000)
<script src="https://vuejs.org/js/vue.js"></script> 
 
<div id="app"> 
 
    <greeting :message="msg"></greeting> 
 
</div> 
 
<script type="text/x-template" id="treeContainer"> 
 
\t <h1>{{message.name}}</h1> 
 
</script>

編輯1:@克雷格的回答可以幫助我傳播基於屬性名稱,並通過對每個屬性的調用來設置的變化。但是,如果數據很複雜,而且問候語是基於節點的許多屬性,那該怎麼辦?在這個例子中,我經歷了一個簡單的用例,但在現實世界中,小部件基於從服務器動態發送的許多屬性,並且每個小部件屬性都基於小部件的類型而有所不同。如「歡迎,{{message.name}}。{{message.location}}處的溫度是{{message.temp}}。」等等。由於節點的屬性不同,是否有任何方法可以更新完整的樹,而無需遍歷JavaScript代碼中的整個樹以及每個屬性的調用集。是否有任何VUE框架可以處理這個問題?

回答

5

Vue除非你使用set方法無法檢測屬性添加或刪除(參見:https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats),所以你需要做的:

Vue.set(data, 'name', 'changed world') 

這裏的的jsfiddle:https://jsfiddle.net/f7ae2364/

編輯

在你的情況,我認爲你將不得不放棄觀看prop,而是去爲如果你想避免遍歷你的數據,你可以使用event bus。所以,首先你建立一個全局總線爲您的組件上聽:

var bus = new Vue({}); 

然後,當您收到新的數據$emit事件到總線上有更新的數據:

bus.$emit('data-updated', data); 

聽着爲組件內部的事件(可放置在創建鉤內),更新的消息,並迫使vue重新渲染的成分(我使用ES6這裏):

created(){ 
    bus.$on('data-updated', (message) => { 
    this.message = message; 
    this.$forceUpdate(); 
    }) 
} 

這裏是JSFiddle:https://jsfiddle.net/9trhcjp4/

+0

感謝您的更新,如果數據是複雜的,並且問候語基於節點的許多屬性會怎麼樣。在這個例子中,我經歷了一個簡單的用例,但在現實世界中,小部件基於從服務器動態發送的許多屬性,並且每個小部件屬性都基於小部件的類型而有所不同。如「歡迎,{{message.name}}。{{message.location}}處的溫度是{{message.temp}}。」等等。由於節點的屬性不同,有沒有什麼辦法可以更新完整的樹而無需遍歷整個樹和每個屬性上的調用集 – Ajay

+0

如果我在Vue之前添加data.name ='更改後的世界' .set(data,'name','changed world1')。這意味着如果對象已經在範圍之外更新了,那麼即使設置操作在設置在同一個鍵上時也無濟於事。有關如何克服這些限制的任何建議? – Ajay

+0

謝謝@craig。解決方案沒有任何小故障。 – Ajay