2
votes

Vue Vuex: les anciennes données restent pendant un certain temps avant les changements de propriété calculés

Je suis nouveau dans vuex et je l'ai encore trop utilisé. Par exemple, j'ai une liste de produits dans mon état boutique . Lorsque je consulte un produit , je passe un appel axios avec ce product.id et je valide les données du produit dans l'état currentProduct . Ensuite, si je visualise un autre produit, la page est rendue avec l'état currentProduct , c'est-à-dire ancien data au début puis après mon action commits .. il est ensuite mis à jour vers currentProduct nouvellement récupéré puis vue change mes données de vue en nouvelles données. L ' utilisateur peut clairement voir les anciennes données remplacées par de nouvelles données. Mais je souhaite charger la page uniquement après que de nouvelles données soient validées dans mon état.

`product.vue`

<div>
    <p>{{currentProduct.name}}</p>
</div>

computed(){

    ...mapState(['currentProduct'])

}

Ma page de rendu:

Cette page affiche les listes de mes produits

'productList.vue'

<div v-for="product in productList" @click="viewProduct(product.id)">
    <p>{{product.name}}</p>
</div>

computed(){

    ...mapState(['productList'])

},
methods:{
    viewProduct(product_id){
        this.$store.state.dispatch('fetchProducts', product_id);
    }
}

Cette page affiche la vue de ce produit particulier

`store.js`

state :{
    productList:{},
    currentProduct:{
     id:'',name:'',price:'','seller'
    }
},
mutations:{
    UPDATE_CURRENT_PRODUCT : (state, data) =>{
     state.currentProduct = Object.assign({},state.currentProduct, data);
    }

},
actions:{
    fetchProducts(){
     const response = fetch...... // logic to fetch product
     commit('UPDATE_CURRENT_PRODUCT', response.data);
    }
}

Dans mon product.vue , les premières anciennes données sont affichées, puis après un certain temps, de nouvelles données les remplacent ... Il manque quelque chose ... Je veux voir les nouvelles données directement sans voir les anciennes données être remplacées par de nouvelles Les données. Y a-t-il un moyen de contourner vuex


1 commentaires

Si vous utilisez Vue Router, vous pouvez utiliser les hooks beforeRouteEnter / beforeRouteUpdate pour mettre à jour les données avant d'ouvrir le composant.


3 Réponses :


-2
votes

Pour cela, vous devez utiliser async await afin que votre composant ne soit mis à jour qu'après la récupération de vos nouvelles données.

async fetchProducts(){
    await const response = fetch...... // logic to fetch product
    commit('UPDATE_CURRENT_PRODUCT', response.data);
   }

Et la même chose dans votre méthode viewProduct. Reportez-vous au lien suivant pour plus de détails (dernier exemple sur la page) https://vuex.vuejs.org/guide/actions.html p >


3 commentaires

ce n'est pas le cas ici .. J'ai déjà des données sur mon 'currentProduct', c'est-à-dire des données précédemment récupérées, donc même son attente asynchrone va toujours récupérer les anciennes données currentProduct et les mettre à jour plus tard après attendre est résolu


Vous pouvez définir state.productList = {} en mutation et appeler cela en cliquant sur votre balise div.


Oui tu peux essayer ça



0
votes

L'élément clé est:

Je souhaite charger la page uniquement après que les nouvelles données soient validées dans mon état

Vous voulez que les méthodes asynchrones se succèdent. Il y a un moyen sympa de faire ça.

Je suppose que dans fetchProducts () un axios récupère / publie les données. Parce qu'axios est basé sur la promesse, vous pouvez revenir avec.

this.$store.state.dispatch('fetchProducts', product_id)
 .then(r=> {if(r){ // get the data from vuex 
 } else { // error
 })
 .catch(e => {});

Ensuite, vous pouvez facilement faire ceci:

fetchProducts() {
 return axios.get('/get/some/data')
    .then(r => { // commit and stuff
     })
    .catch(e => { // error handling
     })
}

Le alors d'expédition court après le alors de l'axe. (par exemple: s'il y a deux axios call what qui doivent être exécutés séquentiellement, vous pouvez appeler le second dans la méthode then de first, et cela résout le problème.)

J'espère que vous comprenez cela. :)


0 commentaires

0
votes

La solution simple serait de réinitialiser les données à une valeur initiale lorsque les actions sont chargées / distribuées.

Alors, essayez de modifier votre code à partir de ceci:

actions:{
    fetchProducts(){
     // Add below line to reset the state when loading.
     commit('UPDATE_CURRENT_PRODUCT', null);
     /***********************************************/
     const response = fetch...... // logic to fetch product
     commit('UPDATE_CURRENT_PRODUCT', response.data);
    }
}

À ceci:

actions:{
    fetchProducts(){
     const response = fetch...... // logic to fetch product
     commit('UPDATE_CURRENT_PRODUCT', response.data);
    }
}

La solution ci-dessus a fonctionné pour moi. J'espère que cela fonctionne pour vous ou pour quelqu'un d'autre.


0 commentaires