如何在Vuex 2中设置初始状态?

我正在为一个小型应用程序使用Vue.js 2.0和Vuex 2.0。我正在通过调用从API检索初始状态的动作在根Vue实例上的“创建的”生命周期挂钩中初始化存储。就像在我的根组件中一样

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: {
 }
});

这很好用。这是我在这里打电话给我的商店的操作:

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

这是使用“ UPDATE_VACATION”提交的突变在这里:

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

我的问题:加载应用程序时,我所有从商店中“获取”值的组件都会引发错误,我试图访问商店中的“未定义”值。换句话说,状态尚未初始化。

例如,我有一个在子组件中具有吸气剂的组件,如下所示:

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

所有这些获取器都会导致错误,因为状态对象上未定义“休假”。对我来说,这似乎是一个异步问题,但可能是错误的。我是否在错误的位置初始化了商店状态?

  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)
    }
}

});

只是这样解决方案对其他人很清楚:

我没有在商店本身中正确设置初始状态。我正在提取数据,并正确更新了商店,但是商店需要像这样初始化:

export default new Vuex.Store({
 state: {
     vacation: {}//I added this, and then justed updated this object on create of the root Vue Instance
 },
});
小卤蛋Stafan2020/03/11 12:24:59

您可以创建一个返回初始状态的函数,并将其用于您的Vuex实例,如下所示:

function initialStateFromLocalStorage() {
    ...
    const empty = {
        status: '',
        token: '',
        user: null
    }
    return empty;
}

export default new Vuex.Store({
    state: initialStateFromLocalStorage,
    ...

一旦为状态返回一个对象,就可以在该函数内执行任何操作,对吗?