我可以从Vuex中的getter发送

时间:2016-11-18 13:46:43

标签: javascript vue.js vue-component vuex vuejs2

小提琴:here

我正在使用Vuex和Vuex创建一个webapp。我有一个商店,我想从getter获取状态数据,我想要的是如果getter发现数据尚未填充,它会调用dispatch并获取数据。

以下是我的Vuex商店:

const state = {
  pets: []
};

const mutations = {
  SET_PETS (state, response) {
    state.pets = response;
  }
};

const actions = {
 FETCH_PETS: (state) => {
      setTimeout(function() { 
            state.commit('SET_PETS', ['t7m12qbvb/apple_9', '6pat9znxz/1448127928_kiwi'])
    }, 1000)
 }
}

const getters = {
    pets(state){
    if(!state.pets.length){
        state.dispatch("FETCH_PETS")
    }
    return state.pets
  }
}

const store = new Vuex.Store({
  state,
  mutations,
  actions,
  getters
});

但我收到以下错误:

  

未捕获的TypeError:state.dispatch不是函数(...)

我知道我可以从Vue组件的beforeMount执行此操作,但我有多个使用相同Vuex存储的组件,因此我必须在其中一个组件中执行此操作,其中一个应该是以及如何它会影响其他组件。

3 个答案:

答案 0 :(得分:7)

Getters无法调用调度,因为它们已通过商店的state而不是context

动作可以在传递上下文时调用state,dispatch,commit。

Getters用于管理“派生状态”。

如果您在需要它的组件上设置pets状态,那么您只需从应用的根目录中调用FETCH_PETS并删除对getter的需求

答案 1 :(得分:6)

我知道这是一篇较旧的帖子,我不确定这是否是好的做法,但我执行了以下操作以从我的商店模块中的 getter 发送:

import store from "../index"

并像这样使用我的 getter 中的 store:

store.dispatch("moduleName/actionName")

我这样做是为了确保数据不存在时可用。

答案 2 :(得分:1)

有同样的问题。.还希望所有Vue实例自动加载某些内容,并编写了一个mixin:

store.registerModule('session', {
    namespaced: true,
    state: {
        session: {hasPermission:{}},
        sessionLoaded:false
    },
    mutations: {
        changeSession: function (state, value)
        {
            state.session = value;
        },
        changeSessionLoaded: function (state)
        {
            state.sessionLoaded = true;
        }

    },
    actions: {
        loadSession(context)
        {
            // your Ajax-request, that will set context.state.session=something
        }
    }
}); 

Vue.mixin({
    computed: {
        $session: function () { return this.$store.state.session.session; },
    },
    mounted:function()
    {
        if(this.$parent==undefined && !this.$store.state.session.sessionLoaded)
        {
            this.$store.dispatch("session/loadSession");
            this.$store.commit("changeSessionLoaded");
        }
    },
});

因为每个vue实例仅加载一个并存储,并且在每个vue实例中自动添加,所以无需在每个主应用中都定义它