Voici la méthode asynchrone des composants de mon enfant:
fetchData() {
return http.getOffers().then((resp) => {
this.offersData = resp.data
})
}
fetchData fait un appel axios pour récupérer des données de l'API. Cependant, dans une vue-devtools (onglet événements), je ne peux voir que les événements, après avoir changé le code et qu'il se recharge à chaud. J'ai également configuré console.log () dans un composant parent:
export default {
/* calculator */
getOffers() {
return HTTP.get('/url')
}
}
Et je ne vois que false code > dans une console. Mon but est d'émettre le loader défini sur true (pour que je puisse montrer le loader), puis de le définir sur false, lorsque les données sont récupérées.
Ma méthode fetchData:
import http from '@/http'
async fetchData() {
await http.getOffers().then((resp) => {
this.offersData = resp.data
})
}
3 Réponses :
Je suggérerais simplement de restructurer votre méthode, car il n'est pas vraiment nécessaire de créer une méthode asynchrone car axios lui-même est asnychronus.
Si vous avez déjà défini la méthode fetchData et que le but est de basculer état du chargeur lorsqu'un appel est en cours, quelque chose comme ça devrait faire.
fetchData () {
this.loader = true
axios.get(url)
.then(resp => this.data = resp)
.then(() => this.loader = false)
}
Bien sûr, ces instructions peuvent être combinées en une seule, mais c'est la même idée. p >
Modifier: (en utilisant la fonction d'émission parente)
fetchData () {
this.$parent.$emit("loader", true)
axios.get(url)
.then(resp => {
this.data = resp
this.$parent.$emit("loader", false)
})
}
Merci, mais ce n'est pas mon cas, car le chargeur lui-même est dans un composant parent, sinon je l'aurais utilisé dans axios promise bien sûr.
J'ai compris. Est-ce que la même chose ne fonctionnerait pas mais pour appeler émettre?
Cela fonctionne dans la promesse axios, mais je veux le faire fonctionner en utilisant async / wait :)
Le problème ici est que créé sur le composant enfant est appelé avant monté sur le composant parent, donc vous commencez à écouter après avoir déjà commencé votre appel Axios.
La méthode d'événement de cycle de vie created ne fait rien avec un retour promis, donc votre méthode revient juste après le début de l'appel Axios et le reste du cycle de vie du composant vue se poursuit.
Vous devriez pouvoir changer votre observation parent en l'événement created pour que cela fonctionne:
created() {
this.$on('loader', (value) => {
console.log(value)
})
}
Si, pour une raison quelconque, vous devez faire quelque chose qui n'est pas accessible dans created , comme accéder à $ el , je suggère de déplacer les deux vers le hook de cycle de vie monté .
Astucieux, je n'ai pas repéré le monté dans le second!
Un bon avis, maintenant mon console.log (valeur) déclenche true et false en même temps. Un problème est survenu avec async maintenant.
Super, c'est ce que tu veux, non? En supposant que fetchData a fait quelque chose entre le true et false
Ils doivent être true et false, de manière synchrone, comme: définissez loader sur true, puis récupérez les données, lorsque les données sont récupérées, définissez loader sur false. Mais maintenant c'est instantanément vrai et faux en même temps,
Ce que je suppose, c'est que votre méthode fetchData ne renvoie pas de promesse. Si fetchData renvoie correctement une promesse, cela devrait attendre que cela se termine. Si possible, pouvez-vous mettre à jour votre question pour inclure ce que cette méthode renvoie? Vous pouvez également tester en remplaçant wait this.fetchData () par await new Promise (resolver => setTimeout (résoudre, 2000)) qui attend juste 2 secondes
J'ai ajouté ma méthode fetchData () , comme vous pouvez le voir, cela ne pose aucun problème. Mais si je $ emit directement dans la promesse axios, cela fonctionne comme prévu. Mais je veux le faire fonctionner en utilisant async / await
Merci! Je pense que votre problème est que vous voudrez retourner la promesse. Changez donc votre déclaration en: return axios.get (url) plutôt que axios.get (url)
Désolé, je n'ai pas vu que vous rendiez en fait la promesse. Je ne suis pas sûr du problème, mais essayez de remplacer votre appel de récupération de données par le wait axios.get (...) et voyez si cela fonctionne.
Qu'est-ce que le changer en console.log (attendez this.fetchData ()) log?
renvoie non défini
Si vous essayez de dire au parent direct qu'il ne se charge plus, vous devrez émettre sur la même instance comme ceci
--Root --My-page.vue -Some-child.vue
En supprimant le $ parent , vous émettrez à partir du composant actuel.
async created () {
this.$emit('loader', true)
await this.fetchData()
this.$emit('loader', false)
}
Vous allez maintenant émettre de some-child.vue vers ma-page.vue . Je n'ai pas essayé, mais théoriquement ce que vous faites en émettant via parent: ( this. $ Parent. $ Emit ('loader', false) ) Vous émettez depuis ma-page. vue à root.
Donc, si vous avez un $ sur ou @loader sur le composant comme donc: , Cela ne fonctionnera jamais car vous émettez du parent.
Disons que j'ai un $ emit dans Some-child, et j'écoute ce $ emit formulaire My-page en utilisant this. $ On code>, puisque this. $ on fonctionne avec $ emit UNIQUEMENT dans la même instance de Vue, c'est pourquoi j'ai utilisé this. $ parent. $ emit < / code>.
Oh, c'est vrai. Cela semble être une solution de contournement, ou? Je n'ai pas utilisé $ sur moi-même. Cependant, j'ai tendance à ajouter les écouteurs à l'élément personnalisé comme vu ci-dessus. Je me trompe peut-être, mais à mes yeux, faire des trucs sur $ parent semble sale car dans le futur, un parent pourrait changer.
On dirait que Vue autorise l'utilisation de $ on avec $ emit comme alternative. Dans quels cas utilisez-vous $ sur ? Je souhaite que Vue devienne strictement opiniâtre, tout comme un angulaire, il ne devrait donc y avoir qu'une seule façon de faire fonctionner un truc.
Oui vous avez raison. Je viens de parcourir à nouveau la documentation pour me rafraîchir la mémoire. Je ne peux personnellement pas trouver un bon cas d'utilisation pour le moment où je voudrais utiliser $ sur . Cependant, il existe un ici . Je crois que la manière "normale" d'émettre des données est de le faire le v-on: / @ way .
Est-ce que
console.log (this)de la méthode async renvoie un objet Vue ou une promesse?Pouvez-vous créer un JSFiddle?
@KubwimanaAdrien, je viens de faire
console.log (this)au lieu deconsole.log (valeur)et j'ai obtenu l'objet Vue.Soyez prudent en faisant
.catch. Cela supprimera TOUTES les erreurs que vous obtenez dans le rappel.thenégalement. Il vaut mieux le faire dans le 2ème paramètre de .then:axios.get ('/ url'). Then ((resp) => {}, (err) => {})infographie