J'essaie de comprendre comment surveiller correctement certaines variations d'accessoires. J'ai un composant parent (fichiers .vue) qui reçoit des données d'un appel ajax, place les données dans un objet et les utilise pour rendre un composant enfant via une directive v-for, sous une simplification de mon implémentation:
<template>
<div>
<player v-for="(item, key, index) in players"
:item="item"
:index="index"
:key="key"">
</player>
</div>
</template>
... puis à l'intérieur de la <script>
balise:
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]);
}
});
}
les objets objets sont comme ceci:
item:{
prop: value,
someOtherProp: {
nestedProp: nestedValue,
myArray: [{type: "a", num: 1},{type: "b" num: 6} ...]
},
}
Maintenant, à l'intérieur du composant "joueur" de mon enfant, j'essaye de surveiller la variation de propriété d'un objet et j'utilise:
...
watch:{
'item.someOtherProp'(newVal){
//to work with changes in "myArray"
},
'item.prop'(newVal){
//to work with changes in prop
}
}
Cela fonctionne mais cela me semble un peu délicat et je me demandais si c'était la bonne façon de procéder. Mon objectif est d'effectuer une action à chaque fois que des prop
changements ou myArray
des éléments nouveaux ou des variations à l'intérieur de ceux existants sont modifiés. N'hésitez pas à nous faire part de vos suggestions.
la source
"item.someOtherProp": function (newVal, oldVal){
comme suggéré par @Ron.keys
intérieur d'un objet? Exemple:"item.*": function(val){...}
Réponses:
Vous pouvez utiliser un observateur profond pour cela:
Cela détectera désormais toutes les modifications apportées aux objets du
item
tableau et les ajouts au tableau lui-même (lorsqu'il est utilisé avec Vue.set ). Voici un JSFiddle: http://jsfiddle.net/je2rw3rs/ÉDITER
Si vous ne souhaitez pas surveiller chaque modification de l'objet de niveau supérieur et souhaitez simplement une syntaxe moins gênante pour regarder directement les objets imbriqués, vous pouvez simplement regarder un à la
computed
place:Voici le JSFiddle: http://jsfiddle.net/oa07r5fw/
la source
computed
place: jsfiddle.net/c52nda7xwatch: { 'item.foo' : function(newVal, oldVal) { // do work here }}
assez lisse. J'adore Vue!Une autre bonne approche et qui est un peu plus élégante est la suivante:
(J'ai appris cette approche de @peerbolte dans le commentaire ici )
la source
ES5
syntaxe. Nous pourrions bien sûr affirmer que leES2015 method definition
lui-même n'est pas très élégant, mais il manque en quelque sorte le point de la question, qui est de savoir comment éviter de mettre le nom entre guillemets. Je suppose que la plupart des gens passent sous silence la question d'origine, qui contient déjà la réponse, et recherchent en fait quelque chose qui, comme vous le dites, n'est pas très bien documenté,VueJs deep watch dans les objets enfants
la source
Vous pouvez utiliser "l'observateur dynamique":
La
$watch
renvoie une fonction de non-surveillance qui arrêtera de regarder si elle est appelée.Vous pouvez également utiliser l'
deep
option:Veuillez vous assurer de consulter les documents
la source
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.
Ne le voyant pas mentionné ici, mais également possible d'utiliser le
vue-property-decorator
modèle si vous étendez votreVue
classe.la source
Une autre façon d'ajouter que j'avais l'habitude de «pirater» cette solution était de le faire: j'ai configuré une
computed
valeur distincte qui retournerait simplement la valeur de l'objet imbriqué.la source
Mon problème avec la réponse acceptée d'utilisation
deep: true
, c'est que lorsque je regarde un tableau en profondeur, je ne peux pas facilement identifier quel élément du tableau contient le changement. La seule solution claire que j'ai trouvée est cette réponse, qui explique comment créer un composant afin que vous puissiez regarder chaque élément du tableau individuellement.la source
oldVal
etnewVal
référencerez tous deux le même objet, ils sont donc les mêmes). L'intention de adeep watcher
est de faire quelque chose lorsque les valeurs changent, comme émettre un événement, effectuer un appel ajax, etc. Sinon, vous voulez probablement un composant, comme indiqué dans la réponse de Mani.Suivi des éléments modifiés individuellement dans une liste
Si vous souhaitez regarder tous les éléments d'une liste et savoir quel élément de la liste a changé, vous pouvez configurer des observateurs personnalisés sur chaque élément séparément, comme suit:
Si votre liste n'est pas remplie immédiatement (comme dans la question d'origine), vous pouvez déplacer la logique hors de l'
created
endroit où vous en avez besoin, par exemple à l'intérieur du.then()
bloc.Regarder une liste changeante
Si votre liste elle-même se met à jour pour avoir des éléments nouveaux ou supprimés, j'ai développé un modèle utile qui "superficiel" surveille la liste elle-même, et surveille / décompresse dynamiquement les éléments lorsque la liste change:
la source
Aucune des réponses pour moi ne fonctionnait. En fait, si vous souhaitez surveiller les données imbriquées avec des composants appelés plusieurs fois. Ils sont donc appelés avec différents accessoires pour les identifier. Par exemple
<MyComponent chart="chart1"/> <MyComponent chart="chart2"/>
ma solution consiste à créer une variable d'état vuex supplémentaire, que je mets à jour manuellement pour pointer vers la dernière propriété mise à jour.Voici un exemple d'implémentation de Vuex.ts:
Sur n'importe quelle fonction de composant pour mettre à jour le magasin:
Maintenant, sur n'importe quel composant pour obtenir la mise à jour:
la source