2017-06-20 3 views
1

ich Probleme mit bin, wo ein berechneter Getter den Zustand greift, bevor es aktualisiert wird, also einen alten Zustand zu machen. Ich habe bereits einige Dinge ausprobiert, zum Beispiel das Zusammenführen von Mutationen mit Aktionen und das Ändern des Status in viele verschiedene Werte, aber der Getter wird immer noch aufgerufen, bevor der Versand beendet ist.Vuex Zugriff Zustand vor async Aktion abgeschlossen ist

Problem

Staat vor Asynchron-Aktion (api-Aufruf) zugegriffen abgeschlossen ist.

-Code-Struktur

  1. Komponente A Lasten API-Daten.
  2. Der Benutzer klickt auf 1 der Daten.
  3. Komponente A sendet geklickte Daten (Objekt) an Komponente B.
  4. Komponente B lädt Objekt empfangen.

Hinweis

Das DOM macht in Ordnung. Dies ist ein Konsolenfehler. Vue schaut sich immer nach DOM-Änderungen um und gibt sie sofort wieder. Die Konsole nimmt jedoch alles auf.

Tor

Prevent Komponente B (die erst nach Komponente genannt wird) aus seiner berechneten Getter-Methode ausgeführt wird vor dem Versand der Komponente A abgeschlossen ist.

Store.js

import Vue from 'vue' 
import Vuex from 'vuex' 
import axios from 'axios'; 

Vue.use(Vuex); 

export const store = new Vuex.Store({ 

    state: { 
    searchResult: {}, 
    selected: null, 
    }, 

    getters: { 
    searchResult: state => { 
     return state.searchResult; 
    }, 
    selected: state => { 
     return state.selected; 
    }, 
    }, 

    mutations:{ 
    search: (state, payload) => { 
     state.searchResult = payload; 
    }, 
    selected: (state, payload) => { 
     state.selected = payload; 
    }, 
    }, 

    actions: { 
    search: ({commit}) => { 
     axios.get('http://api.tvmaze.com/search/shows?q=batman') 
     .then(response => { 
      commit('search', response.data); 
     }, error => { 
      console.log(error); 
     }); 
    }, 

    selected: ({commit}, payload) => { 
     commit('selected', payload); 
    }, 
    }, 

}); 

SearchResult.vue

<template> 
<div> 
    //looped 
    <router-link to="ShowDetails" @click.native="selected(Object)"> 
     <p>{{Object}}</p> 
    </router-link> 
</div> 
</template> 

<script> 
export default { 
    methods: { 
    selected(show){ 
     this.$store.dispatch('selected', show); 
    }, 
    }, 
} 
</script> 

ShowDetails.vue

<template> 
<div> 
    <p>{{Object.name}}</p> 
    <p>{{Object.genres}}</p> 
</div> 
</template> 

<script> 
export default { 
    computed:{ 
    show(){ 
     return this.$store.getters.selected; 
    }, 
    }, 
} 
</script> 

This image shows that the computed method "show" in file 'ShowDetails' runs before the state is updated (which happens BEFORE the "show" computed method. Then, once it is updated, you can see the 2nd console "TEST" which is now actually populated with an object, a few ms after the first console "TEST".

Frage

Vuex alles über Zustand beobachtet und das Management so wie kann ich verhindern, dass diese Konsole Fehler?

Vielen Dank im Voraus.

Antwort

1

store.dispatch kann versprechen, durch die ausgelöste Aktion Handler zurück behandeln und es gibt auch Versprechen. Siehe Composing Actions.

können Sie Setup Ihre ausgewählt Aktion ein Versprechen wie diese zurück:

selected: ({commit}, payload) => { 
    return new Promise((resolve, reject) => { 
     commit('selected', payload); 
    }); 
} 

Dann in Ihrem SearchResults.vue stattdessen ein router-link der Verwendung einer Taste verwenden, und führen Sie programmatic navigation in den Erfolg Rückruf Ihr ausgewählt Aktion Versprechen wie folgt:

<template> 
<div> 
    //looped 
    <button @click.native="selected(Object)"> 
     <p>{{Object}}</p> 
    </button> 
</div> 
</template> 

<script> 
export default { 
    methods: { 
    selected(show){ 
     this.$store.dispatch('selected', show) 
      .then(() => { 
      this.$router.push('ShowDetails'); 
     }); 
    }, 
    }, 
} 
</script> 
0

Initialisieren Sie Ihre Status. Wie bei allen andere Vue‘Daten ist es immer besser ist es am Startpunkt zu initialisieren, auch bei leeren '' oder [] aber VueJS (nicht sicher, ob eckig oder Reagieren das gleiche handeln, aber ich nehme an ähnlich) verhalten sich viel besser ALL mit IHRER VARIABLEN initialisiert.

Sie können den anfänglichen Leerwert Ihrer Status in Ihrer Geschäftsinstanz definieren.

Sie finden das nicht nur hier hilfreich, sondern z.mit Formular-Validierung, da die meisten Plugins mit initialisierten Daten funktionieren, aber nicht mit nicht initialisierten Daten funktionieren.

Ich hoffe, es hilft.

0

können Sie versuchen, v-wenn verwenden Rendering-Vorlage zu vermeiden, wenn es keine Suche ist Ergebnisse

v-if="$store.getters.searchResult" 
Verwandte Themen