2016-11-03 5 views
1

Ich fange gerade an, Vuex hier zu lernen. Bis jetzt habe ich geteilte Daten in einer store.js Akte gespeichert und store in jedes Modul importiert, aber dieses wird ärgerlich und ich bin besorgt über mutierenden Staat.Async-Anrufe mit Vuex machen

Worum ich mich ärgere, ist, wie man Daten von Firebase mit Vuex importiert. Von dem, was ich verstehe, können nur Aktionen Async-Aufrufe ausführen, aber nur Mutationen können den Status aktualisieren?

Im Moment mache ich Anrufe zu Firebase von meinem Mutations-Objekt und es scheint gut zu funktionieren. Ehrlich gesagt scheint der gesamte Kontext, Commit, Dispatch, etc. ein bisschen überlastet zu sein. Ich möchte nur die minimale Menge an Vuex verwenden können, die notwendig ist, um produktiv zu sein.

In der Dokumentation sieht es so aus, als könnte ich Code schreiben, der den Status im Mutationsobjekt wie unten aktualisiert, in meine Komponente in der -Eigenschaft importieren und dann eine Zustandsaktualisierung mit store.commit('increment') auslösen. Dies scheint die minimale Menge zu sein, die notwendig ist, um Vuex zu verwenden, aber wo kommen dann die Aktionen her? Verwirrt :(Jede Hilfe auf dem besten Weg, dies zu tun oder Best Practices wäre willkommen!

const store = new Vuex.Store({ 
    state: { 
    count: 0 
    }, 
    mutations: { 
    increment (state) { 
     state.count++ 
    } 
    } 
}) 

Mein Code ist unten

store.js

import Vue from 'vue' 
import Vuex from 'vuex' 

Vue.use(Vuex); 

const db = firebase.database(); 
const auth = firebase.auth(); 

const store = new Vuex.Store({ 
    state: { 
    userInfo: {}, 
    users: {}, 
    resources: [], 
    postKey: '' 
    }, 
    mutations: { 

    // Get data from a firebase path & put in state object 

    getResources: function (state) { 
     var resourcesRef = db.ref('resources'); 
     resourcesRef.on('value', snapshot => { 
      state.resources.push(snapshot.val()); 
     }) 
    }, 
    getUsers: function (state) { 
     var usersRef = db.ref('users'); 
     usersRef.on('value', snapshot => { 
      state.users = snapshot.val(); 
     }) 
    }, 
    toggleSignIn: function (state) { 
     if (!auth.currentUser) { 
      console.log("Signing in..."); 
      var provider = new firebase.auth.GoogleAuthProvider(); 
      auth.signInWithPopup(provider).then(result => { 
      // This gives you a Google Access Token. You can use it to access the Google API. 
      var token = result.credential.accessToken; 
      // The signed-in user info. 
      var user = result.user; 
      // Set a user 
      var uid = user.uid; 
      db.ref('users/' + user.uid).set({ 
       name: user.displayName, 
       email: user.email, 
       profilePicture : user.photoURL, 
      }); 

      state.userInfo = user; 
      // ... 
      }).catch(error => { 
      // Handle Errors here. 
      var errorCode = error.code; 
      var errorMessage = error.message; 
      // The email of the user's account used. 
      var email = error.email; 
      // The firebase.auth.AuthCredential type that was used. 
      var credential = error.credential; 
      // ... 
      }); 
     } else { 
      console.log('Signing out...'); 
      auth.signOut();  
     } 
    } 
    } 
}) 

export default store 

main.js

import Vue from 'vue' 
import App from './App' 
import store from './store' 

new Vue({ 
    el: '#app', 
    store, // Inject store into all child components 
    template: '<App/>', 
    components: { App } 
}) 

App.vue

<template> 
    <div id="app"> 
    <button v-on:click="toggleSignIn">Click me</button> 
    </div> 
</template> 

<script> 

import Hello from './components/Hello' 


export default { 
    name: 'app', 
    components: { 
    Hello 
    }, 
    created: function() { 
    this.$store.commit('getResources'); // Trigger state change 
    this.$store.commit('getUsers'); // Trigger state change 
    }, 
    computed: { 
    state() { 
     return this.$store.state // Get Vuex state into my component 
    } 
    }, 
    methods: { 
    toggleSignIn() { 
     this.$store.commit('toggleSignIn'); // Trigger state change 
    } 
    } 
} 

</script> 

<style> 

</style> 

Antwort

12

Alle AJAX sollte in Aktionen statt Mutationen gehen. So würde der Prozess durch den Aufruf Ihrer Aktion

... beginnt die

eine Mutation Daten aus dem Ajax-Rückruf verpflichtet ..., die für die Aktualisierung des vuex Zustandes verantwortlich ist.

Referenz: http://vuex.vuejs.org/en/actions.html

Hier ist ein Beispiel:

// vuex store 

state: { 
    savedData: null 
}, 
mutations: { 
    updateSavedData (state, data) { 
    state.savedData = data 
    } 
}, 
actions: { 
    fetchData ({ commit }) { 
    this.$http({ 
     url: 'some-endpoint', 
     method: 'GET' 
    }).then(function (response) { 
     commit('updateSavedData', response.data) 
    }, function() { 
     console.log('error') 
    }) 
    } 
} 

dann Ihre Ajax zu nennen, werden Sie die Aktion aufrufen müssen nun durch dies zu tun:

store.dispatch('fetchData') 

Ersetzen Sie in Ihrem Fall einfach this.$http({...}).then(...) durch Ihren firebase ajax und rufen Sie Ihre Aktion im Callback auf.

+0

das ist ziemlich ausführlich ehrlich. Warum kann 'fetchData' 'saveDate' nicht direkt aktualisieren? Mutation scheint überflüssig zu sein. – Martian2049