ChatGPT解决这个技术问题 Extra ChatGPT

从 Vuex 中的一个模块更改另一个模块状态

我的 vuex 商店中有两个模块。

var store = new Vuex.Store({
    modules: {
        loading: loading 
        posts: posts
    }
});

在模块 loading 中,我有一个属性 saving,它可以设置为 truefalse,并且还有一个名为 TOGGLE_SAVING 的变异函数来设置此属性。

在模块 posts 中,在获取帖子之前和之后,我想更改属性 saving。我是通过从 posts 模块中的一项操作调用 commit('TOGGLE_SAVING') 来实现的。

var getPosts = function (context) {
    context.commit(TOGGLE_LOADING);
};

当它尝试提交时,我在控制台中收到以下错误

[vuex] unknown local mutation type: TOGGLE_LOADING, global type: posts/TOGGLE_LOADING 

如何使用 commit 在另一个模块中改变状态?

如果您收到来自 api 的响应,您将使用 commit('loading/TOGGLE_LOADING', response.data, {root: true})

N
Nikolay Tsenkov

按照建议 here 使用以下参数进行尝试;

commit('TOGGLE_LOADING', null, { root: true })

如果您将 namespaced 设置为 true(在 Nuxt 中,这是模块模式下的默认设置),则变为:

commit('loading/TOGGLE_LOADING', null, { root: true })

如果您正在使用模块和命名空间,请不要忘记将命名空间添加到 commit,如 commit('namespace/TOGGLE_SAVING', null, { root: true }),否则它将不起作用。
这对我不起作用。我只是得到“未知的突变类型”。
我有类似的需求,您的回答解决了我的问题。谢谢你。
非常感谢!它帮助了我
为什么需要 root: true ,确定 Nuxt 应该能够找到其他模块的突变?
J
Julien

您可以使用 action 提交在另一个模块中定义的突变,然后您将在另一个模块中修改状态。

像这样:

posts: {
  actions: {
    toggleSavingActions(context) {
      // some actions 
      context.commit("TOGGLE_SAVING"); // defined in loading module
    }
  }
}

我就是这样做的。我还在两个模块中设置了“命名空间:true”。但我得到[vuex] unknown local mutation type: TOGGLE_LOADING, global type: posts/TOGGLE_LOADING
哦,是的。默认情况下,模块内的操作、突变和 getter 仍然在全局命名空间下注册。所以你可以删除命名空间属性,或者使用 commit('someMutation', null, { root: true })
在我的情况下,如果我使用 namespace: true,我需要执行以下操作:commit('my_module_name/someMutation', null, { root: true })
提交是同步的,而动作是异步的,所以你不应该使用动作来提交突变。
I
Igor Parra

你也可以像往常一样在任何 js 文件中导入 store 并使用它。例如:

// src/state/modules/posts.js

import store from '@/state/store'
...
store.commit('posts/TOGGLE_LOADING')
...

这很好用,唯一的缺点是很难隔离测试或模型。

版本:由于测试问题,最近我使用我提到的技术消除了所有代码。实际上,您始终可以按照推荐的方式更改其他模块的状态,如本例所示。如果您在不同的模块中管理身份验证和配置文件,则非常有用。

logout: context => {
  return new Promise((resolve) => {
    // Clear token in all axios requests
    axios.defaults.headers.common['Authorization'] = ''
    // Logout from firebase
    firebase
      .auth()
      .signOut()
      .then(() => {
        // Update state in profile module
        context.commit('profile/SET_USER', null, {
          root: true
        })
        resolve()
      })
      .catch(error => reject(error))
  })
}

添加 null + setting root true 确实有效。想知道为什么这是必要的? nuxt 应该能够找出外部提交的位置?
r
rebinnaf

如果您在模块中使用了 namespaced: true,有两种方法:

1-您应该添加 { root: true }

commit('TOGGLE_LOADING', null, { root: true }) 

2- 定义如下全局操作(例如 globalToggleLoading)并通过 dispatch('globalToggleLoading') 从您想要的任何模块调用它

globalToggleLoading: {
    root: true,
    handler({ commit }) {
      commit('TOGGLE_LOADING')
    }
  }

如果您的模块是 not namespaced,您可以通过调用 commit、dispatch 来调用任何突变或操作:

commit('TOGGLE_LOADING')