173 votes

Retourner les promesses des actions Vuex

J'ai récemment commencé la migration des choses de jQ à un cadre plus structuré être VueJS, et j'adore ça!

Sur le plan conceptuel, Vuex a été un peu un changement de paradigme pour moi, mais je suis confiant, je sais ce que son tout environ maintenant, et totalement l'obtenir! Mais il existe quelques petites zones d'ombre, surtout à partir d'un point de vue de la mise en œuvre.

Ce que je ressens est bon de par leur conception, mais ne sais pas si c'est en contradiction avec la Vuex cycle de l'uni-directionnelle de flux de données.

En gros, est-il considéré comme une bonne pratique de retour d'une promesse () de l'objet à partir d'une action? - Je traiter ces asynchrones wrappers, avec les états de l'échec et de la comme, semble être un bon ajustement pour le retour d'une promesse. Contrairement mutateurs il suffit de changer les choses, et sont de la pure structures au sein d'un magasin/module.

314voto

Mani Points 11600

actions en Vuex sont asynchrones. La seule façon de faire l'appel de la fonction (initiateur de l'action), à savoir qu'une action est terminée - est par le retour d'une Promesse et d'une résolution plus tard.

Voici un exemple: myAction renvoie un Promise, fait un appel http et résout ou rejette l' Promise plus tard - le tout de manière asynchrone

actions: {
    myAction(context, data) {
        return new Promise((resolve, reject) => {
            // Do something here... lets say, a http call using vue-resource
            this.$http("/api/something").then(response => {
                // http success, call the mutator and change something in state
                resolve(response);  // Let the calling function know that http is done. You may send some data back
            }, error => {
                // http failed, let the calling function know that action did not work out
                reject(error);
            })
        })
    }
}

Maintenant, quand votre Vue de la composante initie myAction, il va obtenir cette Promesse de l'objet et peut savoir si elle a réussi ou non. Voici un exemple de code pour la Vue de composant:

export default {
    mounted: function() {
        // This component just got created. Lets fetch some data here using an action
        this.$store.dispatch("myAction").then(response => {
            console.log("Got some data, now lets show something in this component")
        }, error => {
            console.error("Got nothing from server. Prompt user to check internet connection and try again")
        })
    }
}

Comme vous pouvez le voir ci-dessus, il est très bénéfique pour actions - retour d'un Promise. Sinon il n'y a aucun moyen pour que l'action de l'initiateur de savoir ce qui se passe et quand les choses sont suffisamment stables pour montrer quelque chose sur l'interface utilisateur.

Et une dernière remarque concernant l' mutators - comme vous l'avez justement souligné, ils sont synchrones. Ils changent les choses dans l' state, et sont généralement appelés à partir d' actions. Il n'est pas nécessaire de mélanger Promises avec mutators, comme l' actions gérer cette partie.

Edit: de Mon point de vue sur la Vuex cycle de l'uni-directionnelle de flux de données:

Si vous accédez à des données comme this.$store.state["your data key"] de vos composants, puis le flux de données est uni-directionnel.

La promesse de l'action est de laisser seulement le composant savoir que l'action est terminée.

Le composant peut soit prendre les données de la promesse de résoudre fonction dans l'exemple ci-dessus (pas uni-directionnelle, donc pas recommandé), ou directement à partir de $store.state["your data key"] qui est unidirectionnel et suit la vuex cycle de vie des données.

Le paragraphe ci-dessus suppose que votre mutateur utilise Vue.set(state, "your data key", http_data), une fois le http appel dans votre action.

57voto

Anoop.P.A Points 577

Juste pour une information sur un sujet fermé: vous n’avez pas à créer de promesse, axios en renvoie une elle-même:

Réf.: Https://forum.vuejs.org/t/how-to-resolve-a-promise-object-in-a-vuex-action-and-redirect-to-another-route/18254/4

Exemple:

 export const loginForm = ({commit},data) => {
        return axios.post('http://localhost:8000/api/login',data).then((response) => {
            console.log(response);
            commit('logUserIn',response.data.data);
        }).catch((error) => {
            commit('unAuthorisedUser',{
                error:error.response.data
            })
        })
};
 

9voto

actes

 ADD_PRODUCT : (context,product) => {
  return Axios.post(uri, product).then((response) => {
    if (response.status === 'success') {  
      context.commit('SET_PRODUCT',response.data.data)
    }
    return response.data
  });
});
 

Composant

 this.$store.dispatch('ADD_PRODUCT',data).then((res) => {
  if (res.status === 'success') {
    // write your success actions here....
  } else {
     // write your error actions here...
  }
})
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X