Vuex - mutacje a akcje

0

Hej

Od pewnego czasu poznaję vue.js, mam jednak pewne problemy w zrozumieniu różnic między mutacjami i akcjami w vuex. Dla przykładu postawiłem prosty server w express z jednym route zwracającym tekst "Hello World", symulację opóźnienia odpowiedzi zrealizowany z użyciem timeout.

app.get('/', (req, res) => {
  setTimeout(()=>{
    res.send('Hello World!')
  }, 3000)
})

Poniżej dwa przykłady zapytań http do powyższego serwera.

Przykład 1

W akcji pobieram dane z serwera, po otrzymaniu odpowiedzi wywołuję commit, w którym otrzymaną wartość wrzucam do response.

export const store = new Vuex.Store({
    state: {
        response: '',
        value: 0
    },
    mutations: {
        GetDataFromAPI(state, payload) {
            state.response = payload;
        }
    },
    actions: {
        GetDataFromAPI(context) {
            myInstance.$http.get('http://localhost:3000').then(res => {
                context.commit('GetDataFromAPI', res.data)
            })
            
        }
    },
    getters: {
        response(state) {
            return state.response;
        },
        val(state) {
            return state.value;
        }
    }
})

Wywołanie akcji po kliknięciu buttona, któremu do zdarzenia click przypisałem GetData.

  computed: {
    ...mapGetters(['response', 'val'])
  },
  methods: {
    GetData(){
      this.$store.dispatch('GetDataFromAPI');
      alert("Execuded")
    }
  }

Kliknięcie buttona wywołuje alert, a po 3 sekundach do resaponse wpisywane jest "Hello World!"

Przykład 2

store - bezpośrednio w mutacji wykonuję zapytanie do http, a otrzymane dane wpisuję do response

export const store = new Vuex.Store({
    state: {
        response: '',
        value: 0
    },
    mutations: {
        GetDataFromAPI(state) {
            myInstance.$http.get('http://localhost:3000').then(res => {
                state.response = res.data;
            })
            
        }
    },
    getters: {
        response(state) {
            return state.response;
        },
        val(state) {
            return state.value;
        }
    }
})

Do zdarzenia click na buttonie przypisana funkcja GetData, która wywołuje bezpośrednio commit.

  computed: {
    ...mapGetters(['response', 'val'])
  },
  methods: {
    GetData(){
      this.$store.commit('GetDataFromAPI');
      alert("Execuded")
    }
  }

W efekcie mam dokładnie takie samo działanie jak w przypadku dispath. Alert, a po upływie 3 sekund pojawia się ""Hello World!".

W związku z tym moje pytanie czym różnią się w działaniu mutacje i akcje.

0

Akcje są asynchroniczne (mutacje nie) więc ogólne zalecenie to najpierw wykonać akcję, a z niej dopiero uruchomić mutację szczególnie wtedy jeżeli przed samą mutacja musi zostać wykonany jakiś dodatkowy kod.

0

Staram się zrozumieć zagadnienia mutacji vs akcji. Nie do końca mogę zrozumieć w praktyce te różnice. Trochę inny kod wrzuciłem, który zamiast zapytania do http symuluje asynchroniczność timeoutem.

Przykład 1

    mutations: {
        GetDataFromAPI(state, payload) {
            state.response += payload
        }
    },
    actions: {
        GetDataFromAPI(context) {
            setTimeout(()=>{
                context.commit('GetDataFromAPI', 10)
            }, 1500)    
            
        }
    },

Przykład 2

    mutations: {
        GetDataFromAPI(state, payload) {
            setTimeout(()=>{
                state.response += payload
            }, 1500)  
        }
    },

Przykład pierwszy zgodny z zasadami, wywołuję go z komponentu poprzez dispatch GetDataFromAPI, a akcja po określonym w timeout czasie wywołuje commit GetDataFromAPI, przykład drugi "niepoprawny" wywołuję z komponentu bezpośrednio poprzez commit GetDataFromAPI gdzie jako payload przekazuję 10, generalnie oba przypadki tak samo działają, po upływie 1500ms do tekstu dodawane jest 10. Trochę bez sensu ten kod ale pokazuje działanie akcji i mutacji.

W momencie kiedy uruchamiam asynchroniczną funkcję w mutacji i działa poprawnie moje pojęcie o mutacjach i kodzie asynchronicznym lega w gruzach. Jedyną różnicą w debugerze nie działa poprawnie śledzenie w przypadku bezpośredniego commitowania GetDataFromAP który zawiera w siobie timeut.

1 użytkowników online, w tym zalogowanych: 0, gości: 1