J'essaie de comprendre comment surveiller correctement certaines variations de prop. J'ai un composant parent (fichiers .vue) qui reçoit les données d'un appel ajax, les place dans un objet et les utilise pour rendre un composant enfant via une directive v-for, en-dessous d'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 balise <script>
:
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 sont comme ceci:
item:{
prop: value,
someOtherProp: {
nestedProp: nestedValue,
myArray: [{type: "a", num: 1},{type: "b" num: 6} ...]
},
}
Maintenant, dans le composant "joueur" de mon enfant, j'essaie de surveiller la variation de propriété d'un élément 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 le faire. Mon objectif est d'effectuer une action à chaque fois que prop
change ou myArray
obtienne de nouveaux éléments ou des variations à l'intérieur des éléments existants. N'hésitez pas à nous faire part de vos suggestions.
Vous pouvez utiliser un observateur profond pour cela:
watch: {
item: {
handler(val){
// do stuff
},
deep: true
}
}
Cela détectera maintenant toute modification apportée aux objets du tableau item
et les ajouts au tableau lui-même (si utilisé avec Vue.set ). Voici un JSFiddle: http://jsfiddle.net/je2rw3rs/
EDIT
Si vous ne souhaitez pas surveiller chaque modification apportée à l'objet de niveau supérieur et souhaitez simplement utiliser une syntaxe moins complexe pour surveiller directement les objets imbriqués, vous pouvez simplement regarder un computed
à la place:
var vm = new Vue({
el: '#app',
computed: {
foo() {
return this.item.foo;
}
},
watch: {
foo() {
console.log('Foo Changed!');
}
},
data: {
item: {
foo: 'foo'
}
}
})
Voici le JSFiddle: http://jsfiddle.net/oa07r5fw/
Une autre bonne approche, légèrement plus élégante, est la suivante:
watch:{
'item.someOtherProp': function (newVal, oldVal){
//to work with changes in someOtherProp
},
'item.prop': function(newVal, oldVal){
//to work with changes in prop
}
}
(J'ai appris cette approche de @peerbolte dans le commentez ici )
Une autre méthode.
Ne pas utiliser fonction flèche en le faisant. Vous ne pouvez pas accéder à l'objet this.
watch:{
'item.someOtherProp': function(newValue, oldValue){
// Process
}
}
Comment faire si vous voulez regarder une propriété pendant un moment et ensuite la dé-regarder?
Ou regarder une propriété de composant enfant de bibliothèque?
Vous pouvez utiliser "l'observateur dynamique":
this.$watch(
'object.property', //what you want to watch
(newVal, oldVal) => {
//execute your code here
}
)
$watch
renvoie une fonction d'annulation de la correspondance qui arrête de regarder si elle est appelée.
var unwatch = vm.$watch('a', cb)
// later, teardown the watcher
unwatch()
Aussi, vous pouvez utiliser l'option deep
:
this.$watch(
'someObject', () => {
//execute your code here
},
{ deep: true }
)
S'il vous plaît assurez-vous de jeter un oeil à la documentation
Ne le voyez pas mentionné ici, mais vous pouvez également utiliser le modèle vue-property-decorator
si vous étendez votre classe Vue
.
import { Watch, Vue } from 'vue-property-decorator';
export default class SomeClass extends Vue {
...
@Watch('item.someOtherProp')
someOtherPropChange(newVal, oldVal) {
// do something
}
...
}
VueJs montre en profondeur dans les objets enfants
new Vue({
el: "#myElement",
data: {
entity: {
properties: []
}
},
watch: {
'entity.properties': {
handler: function (after, before) {
// Changes detected. Do work...
},
deep: true
}
}
});
Mon problème avec la réponse acceptée d’utiliser deep: true
, c’est que lorsqu’on regarde en profondeur un tableau, je ne peux pas facilement identifier quel élément de le tableau contient le changement. La seule solution claire que j'ai trouvée est cette réponse explique comment créer un composant afin que vous puissiez observer chaque élément de tableau individuellement.
Une autre façon d’ajouter que j’avais l'habitude de "pirater" cette solution consistait à procéder ainsi: j'ai créé une valeur séparée computed
qui renverrait simplement la valeur de l'objet imbriqué.
data : function(){
return {
my_object : {
my_deep_object : {
my_value : "hello world";
}.
},
};
},
computed : {
helper_name : function(){
return this.my_object.my_deep_object.my_value;
},
},
watch : {
helper_name : function(newVal, oldVal){
// do this...
}
}