【问题标题】:Change another module state from one module in Vuex从 Vuex 中的一个模块更改另一个模块状态
【发布时间】:2017-07-25 04:04:32
【问题描述】:

我的 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) {
    contex.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})

标签: vue.js vuejs2 vuex


【解决方案1】:

按照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 应该能够找到其他模块的突变?
【解决方案2】:

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

// src/state/modules/posts.js

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

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


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

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 + 设置 root true 确实有效。想知道为什么这是必要的? nuxt 应该能够找出外部提交所在的位置?
【解决方案3】:

您可以使用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:真的})
  • 如果我使用namespace: true,我需要做下一个:commit('my_module_name/someMutation', null, { root: true })
  • 一个提交是同步的,而一个动作是异步的,所以你不应该使用一个动作来提交一个突变。
【解决方案4】:

如果您在模块中使用了 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')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-12
    • 2021-11-07
    • 2018-05-02
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 2011-04-01
    相关资源
    最近更新 更多