2017-01-23 4 views
2

propagieren Ich bin ziemlich neu in Vue Framework. Ich versuche, die Änderungen von Eltern zu Kind zu übertragen, wenn die Attribute hinzugefügt oder entfernt oder zu einem späteren Zeitpunkt außerhalb der Komponente aktualisiert werden. Im folgenden Ausschnitt versuche ich eine Komponente zu schreiben, die eine Begrüßungsnachricht basierend auf dem Namensattribut des Knotens zeigt, der vom übergeordneten Knoten als Eigenschaft übergeben wird.Vue JS nicht Änderungen von Eltern zu Komponente

Alles funktioniert wie erwartet, wenn der Knoten das Attribut "name" (im folgenden Ausschnitt kommentiert) bei der Initialisierung enthält. Aber wenn das Namensattribut hinzugefügt wird, eine spätere Stufe der Ausführung (hier zu Demonstrationszwecken habe ich ein Set-Timeout hinzugefügt und angewendet). Die Komponente löst einen Fehler aus und die Änderungen werden nicht wiedergegeben. Ich bin nicht sicher, wie ich Änderungen für dynamische Attribute in der Komponente propagieren kann, die basierend auf anderen Ereignissen außerhalb der Komponente generiert werden.

Grundsätzlich wollte ich die Komponente, die verschiedene Arten von Widgets basierend auf Server-Antwort auf dynamische Weise basierend auf der Eigenschaft aktualisiert aktualisiert werden.Wenn die Eigenschaft aktualisiert wird, würde ich gerne die Komponente selbst aktualisieren. Warum funktioniert die Zwei-Wege-Bindung in Vuejs nicht richtig?

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>

Edit 1: @ Craig Antwort hilft mir, Änderungen auf dem Attributnamen basiert zu verbreiten und durch auf jedem der Attribut aufrufen. Was aber, wenn die Daten komplex sind und die Begrüßung auf vielen Attributen des Knotens basiert? Hier im Beispiel habe ich einen einfachen Anwendungsfall durchgespielt, aber in der Praxis basiert das Widget auf vielen Attributen, die dynamisch vom Server gesendet werden, und die Attribute jedes Widgets unterscheiden sich je nach Art des Widgets. wie "Willkommen, {{message.name}}. Temperatur bei {{message.location}} ist {{message.temp}}." und so weiter. Da die Attribute des Knotens unterschiedlich sind, gibt es eine Möglichkeit, den kompletten Baum zu aktualisieren, ohne den gesamten Baum in unserem JavaScript-Code durchlaufen zu müssen und Call-Set für jedes Attribut. Gibt es irgendetwas im VUE-Framework, das dafür sorgen kann?

Antwort

5

Vue nicht Eigenschaft Hinzufügen oder Löschen erkennen können, wenn Sie die set Methode verwenden (siehe: https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats), so müssen Sie tun, um:

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

die JSFiddle hier: https://jsfiddle.net/f7ae2364/

EDIT

In Ihrem Fall, ich denke, Sie müssen aufhören, die prop zu sehen und stattdessen gehen ein event bus, wenn Sie vermeiden möchten, Ihre Daten zu durchlaufen.Also, zuerst setzen Sie einen globalen Bus oben für Ihre Komponente hören auf:

var bus = new Vue({}); 

Dann, wenn Sie neue Daten erhalten Sie $emit das Ereignis auf den Bus mit den aktualisierten Daten:

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

Und hören für dieses Ereignis in Ihrer Komponente (die innerhalb des erstellten Haken platziert werden können), um die Nachricht zu aktualisieren und vue zwingen, die Komponente neu zu machen (I ES6 hier bin mit):

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

Hier ist der JSFiddle: https://jsfiddle.net/9trhcjp4/

+0

Danke für das Update, was ist, wenn die Daten komplex waren und die Begrüßung auf vielen Attributen des Knotens basiert. Hier im Beispiel habe ich einen einfachen Anwendungsfall durchgespielt, aber in der Praxis basiert das Widget auf vielen Attributen, die dynamisch vom Server gesendet werden, und die Attribute jedes Widgets unterscheiden sich je nach Art des Widgets. wie "Willkommen, {{message.name}}. Temperatur bei {{message.location}} ist {{message.temp}}." und so weiter. Da die Attribute des Knotens unterschiedlich sind, gibt es eine Möglichkeit, den kompletten Baum zu aktualisieren, ohne durch den gesamten Baum zu gehen und Call-Set für jedes Attribut – Ajay

+0

Auch Ihr Code funktioniert nicht, wenn ich data.name = 'Changed world' vor Vue .set (Daten, 'Name', 'veränderte Welt1'). Das bedeutet, wenn das Objekt bereits außerhalb des Gültigkeitsbereichs aktualisiert wurde und dann auch die eingestellte Operation nicht hilft, wenn es auf denselben Schlüssel gesetzt wird. Irgendwelche Ratschläge, wie man diese Beschränkungen überwinden kann? – Ajay

+0

Danke @craig. Lösungen funktionieren ohne Störungen. – Ajay