36

小提琴:这里

我正在使用带有 Vuex 的 Vue 2 创建一个 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
});

但我收到以下错误:

未捕获的类型错误:state.dispatch 不是函数(…)

我知道我可以从beforeMountVue 组件中做到这一点,但是我有多个使用相同 Vuex 存储的组件,所以我必须在其中一个组件中执行此操作,应该是哪个组件以及它将如何影响其他组件。

4

4 回答 4

21

Getter 不能调用 dispatch,因为它们是通过store的statenotcontext

动作可以在传递上下文时调用状态、调度、提交。

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

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

于 2016-11-18T14:16:03.380 回答
10

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

import store from "../index"

并像这样使用我的吸气剂内部的商店:

store.dispatch("moduleName/actionName")

我这样做是为了确保数据在不存在的情况下可用。

*编辑:我想让你知道这一点:Vue form - getter and side effects

这与@storsoc 注释有关。

如果你需要从你的 getter 发送,你可能已经错误地实现了你的状态。也许更高级别的组件之前应该已经获取了数据(状态提升)。另外请注意,只有在需要从当前状态派生其他数据才能将其提供给模板之前才应使用 getter,否则您可以直接调用状态:this.$store.state.variable在方法/计算属性中使用。

还有关于您的生命周期方法的事情。例如,您可以在已安装或已创建的方法中检查状态是否已设置,否则从那里分派。如果您的 getter /“直接状态”在计算属性内,它应该能够检测到更改。

于 2021-03-04T15:08:57.823 回答
6

有同样的问题..还希望所有 Vue-Instances 自动加载一些东西,并写了一个 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-instance 只加载一个并存储,并且它自动包含在每个 vue-instance 中,因此无需在每个主应用程序中定义它

于 2018-08-14T08:53:25.117 回答
0

我使用 getter 来配置动态页面。本质上,是这样的:

getter: {
  configuration: function () {
    return {
      fields: [
        {
          component: 'PlainText',
          props: {},
          setPropsFromPageState: function (props, pageState, store) {
            // custom logic
          }
        }
      ]
    };
  }
}

然后在页面组件中,当我在动态组件上动态设置props时,我可以调用该setPropsFromPageState(field.props, this.details, this.$store)组件的方法,允许在config级别设置逻辑来修改传入的props的值,或者提交/dispatch 如果需要。

基本上,这只是一个存储在 getter 中的回调函数,它在组件上下文中执行,并通过它访问 $store。

于 2021-10-13T17:09:52.470 回答