J'utilise Vue Resource pour récupérer une collection d'images à partir d'une API REST. La demande est envoyée dans le hook created
de mon composant Vue.
Le problème est que j'essaie d'accéder aux données extraites via le hook mounted
, mais les données ne sont pas chargées.
Je reçois cette erreur dans la console:
[Vue warn]: Erreur dans le crochet monté: "TypeError: Impossible de lire la propriété 'forEach' of indéfinie"
Voici mon composant:
<script>
export default {
data() {
return { imgs : '' };
},
created() {
// the full url is declare in my main.js
this.imgs = this.$resource('acf/v3/pages/4');
this.imgs.query().then((response) => {
console.log('success', response);
this.imgs = response.data.acf.gallery;
}, (response) => {
console.log('erreur', response);
});
},
mounted() {
// get the ref="image" in my dom template
let imgs = this.$refs.image;
imgs.forEach((img) => {
// I do some stuff with imgs
});
}
}
</script>
Si j'emballe une setTimeout
autour du contenu de mounted
, tout fonctionne correctement.
Donc, je ne comprends pas comment je peux attendre que mes données se chargent avant que le hook mounted
ne soit exécuté. N'est-ce pas le rôle des crochets du cycle de vie Vue?
Puisque l'appel this.imgs.query()
est asynchrone, votre hook mounted
est appelé avant que le gestionnaire then
ne définisse this.imgs
(ce qui, je suppose, est lié à v-for
à un élément de votre modèle avec un attribut ref="image"
). Ainsi, même si le composant a été monté sur le DOM, le $refs
n'a pas encore été configuré.
Je ferais une méthode pour "faire des choses avec imgs" et ensuite appeler cette méthode dans un $nextTick
callback dans le gestionnaire then
de l'appel async. Le rappel transmis à $nextTick
sera "exécuté après le prochain cycle de mise à jour du DOM", ce qui signifie que le $refs
sera configuré à ce stade.
<script>
export default {
data() {
return { imgs: '' };
},
created() {
// the full url is declare in my main.js
this.imgs = this.$resource('acf/v3/pages/4');
this.imgs.query().then((response) => {
console.log('success', response);
this.imgs = response.data.acf.gallery;
this.$nextTick(() => this.doStuffWithImgs());
}, (response) => {
console.log('erreur', response);
});
},
methods: {
doStuffWithImgs() {
// get the ref="image" in my dom template
let imgs = this.$refs.image;
imgs.forEach((img) => {
// I do some stuff with imgs
});
}
}
}
</script>
Comme indiqué dans le Lifecycle Diagram of Instance Vue. Après Mounted Hook (ce qui signifie que nous pouvons accéder au DOM), il existe également des hooks beforeUpdate et mis à jour. Ces crochets peuvent être utilisés lorsque les données sont modifiées. Je pense que beforeUpdate ou le hook de mise à jour peut être utilisé après avoir récupéré les données dans le hook créé.
<script>
export default {
data() {
return { imgs : '' };
},
created() {
// the full url is declare in my main.js
this.imgs = this.$resource('acf/v3/pages/4');
this.imgs.query().then((response) => {
console.log('success', response);
this.imgs = response.data.acf.gallery;
}, (response) => {
console.log('erreur', response);
});
},
// here we can use beforeUpdate or updated hook instead of mounted
beforeUpdate() {
// get the ref="image" in my dom template
let imgs = this.$refs.image;
imgs.forEach((img) => {
// I do some stuff with imgs
});
}
}
J'espère que ça aide.
Je rappelle que je suis nouveau pour VueJS et que j'apprends de nos jours).