type mapactions from example ejemplo actions vue.js vuejs2 vuex

vue.js - mapactions - vuex ejemplo



¿Cómo configuro el estado inicial en Vuex 2? (1)

Estoy usando Vue.js 2.0 y Vuex 2.0 para una aplicación pequeña. Estoy inicializando el almacén en el gancho de ciclo de vida ''creado'' en la instancia de Vue raíz llamando a una acción que recupera el estado inicial de una API ... así en mi Componente Raíz :

const app = new Vue({ el: "#app", router, store, data: { vacation: {}, }, components: { ''vacation-status'': VacationStatus, }, created(){ //initialize store data structure by submitting action. this.$store.dispatch(''getVacation''); }, computed: { }, methods: { } });

Esto está funcionando bien. Aquí está la acción en mi tienda que estoy llamando aquí:

getVacation({commit}){ api.getVacation().then(vacation => commit(UPDATE_VACATION, vacation)) }

La mutación que esto está cometiendo con ''UPDATE_VACATION'' está aquí:

[UPDATE_VACATION] (state, payload) { state.vacation = payload.vacation; },

Mi problema: cuando cargo la aplicación, todos mis componentes que están ''obteniendo'' valores de la tienda arrojan errores. Estoy tratando de acceder a valores ''indefinidos'' en la tienda. En otras palabras, el estado aún no se ha inicializado.

Por ejemplo, tengo un componente que tiene captadores en componentes secundarios como este:

computed: { arrival () { return this.$store.getters.arrival }, departure() { return this.$store.getters.departure }, countdown: function() { return this.$store.getters.countdown } }

Todos estos captadores causan errores porque "vacaciones" no está definido en el objeto de estado. Me parece un problema asíncrono, pero podría estar equivocado. ¿Estoy inicializando el estado de mi tienda en el lugar equivocado?

Vue.use(Vuex); export default new Vuex.Store({ state: {}, getters: { getVacation: state => { return state.vacation }, guests: state => { return state.vacation.guests }, verifiedGuests: state => { return state.vacation.guests.filter(guest => guest.verified) }, emergencyContacts: state => { return state.emergency_contacts }, arrival: state => { return state.vacation.check_in }, departure: state => { return state.vacation.check_out }, countdown : state => { let check_in = new Date(state.vacation.check_in); let now = new Date(); if ((now - check_in) > 0) { return ''This vacation started on '' + check_in; } let difference = check_in - now; let day = 1000 * 60 * 60 * 24; return Math.ceil(difference / day) + " days until your vacation"; } }, mutations: { [UPDATE_VACATION] (state, payload) { state.vacation = payload.vacation; }, [ADD_GUEST] (state, payload) { state.vacation.guests.push(payload.guest); }, [REMOVE_GUEST] (state, payload){ state.vacation.guests.filter(guest => { debugger; return guest.id != payload.guest.id}) }, [UPDATE_GUEST] (state, payload){ state.vacation.guests.map(guest => { // Refactor Object.assign to deep cloning of object return guest.id === payload.guest.id ? Object.assign({}, guest, payload.guest) : guest; }) }, [ADD_EMERGENCY] (state, payload){ state.vacation.emergency_contacts.push(payload.emergency_contact) }, [REMOVE_EMERGENCY] (state, payload){ state.vacation.emergency_contacts.filter(contact => contact.id !== payload.emergency_contact.id) }, [UPDATE_EMERGENCY] (state, payload){ state.vacation.emergency_contacts.map(contact => { // Refactor not needed because emergency_contact is a shallow object. return contact.id === payload.emergency_contact.id ? Object.assign({}, contact, payload.emergency_contact) : contact; }); } }, actions: { getVacation({commit}){ api.getVacation().then(vacation => commit(UPDATE_VACATION, vacation)) }, addGuest({commit}, guest){ commit(ADD_GUEST, guest); }, removeGuest({commit}, guest){ commit(REMOVE_GUEST, guest); }, updateGuest({commit}, guest){ commit(UPDATE_GUEST, guest); }, addEmergency({commit}, guest){ commit(ADD_EMERGENCY, contact) }, removeEmergency({commit}, contact){ commit(REMOVE_EMERGENCY, contact) }, updateEmergency({commit}, contact){ commit(UPDATE_EMERGENCY, contact) }, updateServer(store, payload){ return api.saveVacation(payload) } }

});

Solo para que la solución sea clara para los demás:

No estaba configurando mi estado inicial de manera adecuada en la tienda. Estaba recogiendo los datos y actualizando la tienda correctamente, pero la tienda necesitaba inicializarse así:

export default new Vuex.Store({ state: { vacation: {}//I added this, and then justed updated this object on create of the root Vue Instance }, });


Creo que estás haciendo todo bien. Quizás no esté creando correctamente los captadores (no puede ver ninguna definición en su código). O bien, no está configurando correctamente el estado inicial (tampoco está visible en su fragmento).

Yo usaría mapState para tener las propiedades del estado disponibles en los componentes.

En la demostración, simplemente agregue users a la matriz en el parámetro del método mapState y los datos de los usuarios estarán disponibles en el componente. (Acabo de agregar a los users getter para mostrar cómo funciona esto. No es necesario si estás usando mapState).

Por favor, eche un vistazo a la demostración a continuación o este fiddle .

const api = ''https://jsonplaceholder.typicode.com/users'' const UPDATE_USERS = ''UPDATE_USERS'' const SET_LOADING = ''SET_LOADING'' const store = new Vuex.Store({ state: { users: {}, loading: false }, mutations: { [UPDATE_USERS](state, users) { console.log(''mutate users'', users) state.users = users; console.log(state) }, [SET_LOADING](state, loading) { state.loading = loading; } }, getters: { users(state) { return state.users } }, actions: { getUsers({commit}) { commit(SET_LOADING, true); return fetchJsonp(api) .then((users) => users.json()) .then((usersParsed) => { commit(UPDATE_USERS, usersParsed) commit(SET_LOADING, false) }) } } }) const mapState = Vuex.mapState; const Users = { template: ''<div><ul><li v-for="user in users">{{user.name}}</li></ul></div>'', computed: mapState([''users'']) } new Vue({ el: ''#app'', store: store, computed: { ...mapState([''loading'']), //...mapState([''users'']), /*users () { // same as mapState return this.$store.state.users; }*/ users() { // also possible with mapGetters([''users'']) return this.$store.getters.users } }, created() { this.$store.dispatch(''getUsers'') }, components: { Users } })

<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch-jsonp/1.0.5/fetch-jsonp.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.1.1/vuex.min.js"></script> <div id="app"> <div v-if="loading">loading...</div> <users></users> <pre v-if="!loading">{{users}}</pre> </div>