Ich versuche zu verstehen, wie man richtig auf Requisitenvariationen achtet. Ich habe eine übergeordnete Komponente (.vue-Dateien), die Daten von einem Ajax-Aufruf empfängt, die Daten in ein Objekt einfügt und damit eine untergeordnete Komponente über eine v-for-Direktive rendert, unter einer Vereinfachung meiner Implementierung:
<template>
<div>
<player v-for="(item, key, index) in players"
:item="item"
:index="index"
:key="key"">
</player>
</div>
</template>
... dann im <script>
Tag:
data(){
return {
players: {}
},
created(){
let self = this;
this.$http.get('../serv/config/player.php').then((response) => {
let pls = response.body;
for (let p in pls) {
self.$set(self.players, p, pls[p]);
}
});
}
Objektobjekte sind wie folgt:
item:{
prop: value,
someOtherProp: {
nestedProp: nestedValue,
myArray: [{type: "a", num: 1},{type: "b" num: 6} ...]
},
}
Jetzt versuche ich in meiner untergeordneten "Player" -Komponente, nach den Eigenschaftsvarianten eines Elements zu suchen, und verwende Folgendes:
...
watch:{
'item.someOtherProp'(newVal){
//to work with changes in "myArray"
},
'item.prop'(newVal){
//to work with changes in prop
}
}
Es funktioniert, aber es scheint mir ein bisschen schwierig zu sein und ich habe mich gefragt, ob dies der richtige Weg ist. Mein Ziel ist es, jedes Mal eine Aktion auszuführen, wenn prop
sich myArray
neue Elemente oder Variationen innerhalb bestehender ändern oder erhalten. Jeder Vorschlag wird geschätzt.
quelle
"item.someOtherProp": function (newVal, oldVal){
Sie einfach wie von @Ron vorgeschlagen.keys
innerhalb eines Objekts auf eine Veränderung zu achten? Beispiel:"item.*": function(val){...}
Antworten:
Sie können dafür einen Deep Watcher verwenden :
Dadurch werden nun alle Änderungen an den Objekten im
item
Array und Ergänzungen am Array selbst erkannt (bei Verwendung mit Vue.set ). Hier ist eine JSFiddle: http://jsfiddle.net/je2rw3rs/BEARBEITEN
Wenn Sie nicht auf jede Änderung am Objekt der obersten Ebene achten möchten und nur eine weniger umständliche Syntax zum direkten Überwachen verschachtelter Objekte wünschen, können Sie
computed
stattdessen einfach Folgendes beobachten :Hier ist die JSFiddle: http://jsfiddle.net/oa07r5fw/
quelle
computed
stattdessen Folgendes ansehen : Folgendes jsfiddle.net/c52nda7xwatch: { 'item.foo' : function(newVal, oldVal) { // do work here }}
ziemlich schlau. Ich liebe Vue!Ein weiterer guter Ansatz, der etwas eleganter ist, lautet wie folgt:
(Ich habe diesen Ansatz von @peerbolte im Kommentar hier gelernt )
quelle
ES5
Syntax. Wir könnten natürlich argumentieren, dass dasES2015 method definition
selbst nicht sehr elegant ist, aber es verfehlt irgendwie den Punkt der Frage, wie man vermeiden kann, den Namen in Anführungszeichen zu setzen. Ich vermute, die meisten Leute beschönigen die ursprüngliche Frage, die bereits die Antwort enthält, und suchen tatsächlich nach etwas, das, wie Sie sagen, nicht sehr gut dokumentiert istVueJs tiefe Beobachtung in untergeordneten Objekten
quelle
Sie können den "dynamischen Beobachter" verwenden:
Das
$watch
gibt eine Unwatch-Funktion zurück, die die Überwachung beendet, wenn sie aufgerufen wird.Sie können auch die
deep
Option verwenden:Bitte schauen Sie sich unbedingt die Dokumente an
quelle
Note that you should not use an arrow function to define a watcher (e.g. searchQuery: newValue => this.updateAutocomplete(newValue)). The reason is arrow functions bind the parent context, so this will not be the Vue instance as you expect and this.updateAutocomplete will be undefined.
Hier wird es nicht erwähnt, aber es ist auch möglich, das
vue-property-decorator
Muster zu verwenden , wenn Sie IhreVue
Klasse erweitern.quelle
Eine andere Möglichkeit, hinzuzufügen, dass ich diese Lösung "gehackt" habe, bestand darin, Folgendes zu tun: Ich habe einen separaten
computed
Wert eingerichtet, der einfach den Wert des verschachtelten Objekts zurückgibt.quelle
Mein Problem mit der akzeptierten Antwort der Verwendung
deep: true
ist, dass ich beim genauen Betrachten eines Arrays nicht leicht identifizieren kann, welches Element des Arrays die Änderung enthält. Die einzige klare Lösung, die ich gefunden habe, ist diese Antwort, in der erklärt wird, wie eine Komponente erstellt wird, damit Sie jedes Array-Element einzeln betrachten können.quelle
oldVal
undnewVal
beide verweisen auf dasselbe Objekt, also sind sie gleich). Die Absicht von adeep watcher
ist es , etwas zu tun, wenn sich die Werte ändern, z. B. ein Ereignis ausgeben, einen Ajax-Aufruf ausführen usw. Andernfalls möchten Sie wahrscheinlich eine Komponente, wie in Manis Antwort ausgeführt.Verfolgung einzelner geänderter Elemente in einer Liste
Wenn Sie alle Elemente in einer Liste anzeigen möchten und wissen möchten, welches Element in der Liste geändert wurde, können Sie benutzerdefinierte Beobachter für jedes Element separat einrichten, z. B.:
Wenn Ihre Liste nicht sofort ausgefüllt ist (wie in der ursprünglichen Frage), können Sie die Logik
created
nach Bedarf verschieben, z.then()
. Blocks.Eine Änderungsliste ansehen
Wenn Ihre Liste selbst aktualisiert wird, um neue oder entfernte Elemente zu erhalten, habe ich ein nützliches Muster entwickelt, das die Liste selbst "flach" überwacht und Elemente dynamisch überwacht / deaktiviert, wenn sich die Liste ändert:
quelle
Keine der Antworten für mich funktionierte. Eigentlich, wenn Sie verschachtelte Daten überwachen möchten, wobei Komponenten mehrmals aufgerufen werden. Deshalb werden sie mit verschiedenen Requisiten angerufen, um sie zu identifizieren. Zum Beispiel
<MyComponent chart="chart1"/> <MyComponent chart="chart2"/>
Meine Problemumgehung besteht darin, eine zusätzliche Vuex-Statusvariable zu erstellen, die ich manuell aktualisiere, um auf die zuletzt aktualisierte Eigenschaft zu verweisen.Hier ist ein Implementierungsbeispiel für Vuex.ts:
Bei jeder Komponentenfunktion zum Aktualisieren des Speichers:
Jetzt auf jeder Komponente, um das Update zu erhalten:
quelle