【问题标题】:Vue.js Vuex State Never Updates With push()Vue.js Vuex 状态从不使用 push() 更新
【发布时间】:2019-04-03 14:07:11
【问题描述】:

我有一个管理数组 (state.all) 的 Vuex 存储,我有一个调用 Vuex 操作的按钮,该操作执行 HTTP 调用,然后通过突变。但是,状态永远不会更新,组件永远不会更新。

为了证明我没有发疯,我在突变内部使用了两个alert()s,以确保我知道我在代码中的位置。 alert()s 总是以正确的值触发。

这是截断的 Vuex 存储(这是一个模块):

const state = {
    all: []
}

// actions
const actions = {
    ...
    runner ({ commit, rootState }, { did, tn }) {
       HTTP.post(url, payload)
           .then(function (response) {
               commit('setNewConversations', response.data)
           })
       })
    }
}

const mutations = {
    ...
    setNewConversations(state, new_conv) {
        for (let new_c_i in new_conv) {
            let new_c = new_conv[new_c_i]
            alert(new_c) // I always see this, and it has the correct value
            if (!(new_c in state.all)) {
                alert('I ALWAYS SEE THIS!') // testing
                state.all.push(new_c)
            }
        }
    }
    ...
}

当我去测试这个时,我看到了我的两个alert()s,第一个是我期望的值,第二个是“我总是看到这个!”但是我的v-for 组件没有任何反应,并且状态永远不会更新,尽管state.all.push()

解决此问题的下一步是什么? JS 控制台中没有错误,我无法弄清楚状态不会更新的任何原因。

谢谢!

【问题讨论】:

  • 你确定它没有更新商店吗?也许由于某种原因视图没有更新?
  • 现在当我删除我的alert() 时,它突然开始工作。现在这是一个偶尔发生的问题。我该怎么做才能弄清楚为什么会这样?
  • 你是否在浏览器中安装了vue devtools extension/plugin/whatever,这是监控 vuex 状态的好方法

标签: vue.js vuex


【解决方案1】:

一种可能的解决方案不是推送到当前状态值,而是将 state.all 的先前值存储在一个新数组中,然后将新更改推送到该新数组。

完成后,将新数组分配给state.all,如下所示。

 setNewConversations(state, new_conv) {
    const prevState = [...state.all];
    for (let new_c_i in new_conv) {
        let new_c = new_conv[new_c_i]
        if (!(new_c in prevState)) {
          prevState.push(new_c);
        }
    }
    state.all = prevState;
}

【讨论】:

  • 为什么我会在这种特殊情况下使用const
  • @David 为什么不呢?你可以把东西推到一个 const 数组中,你知道的
  • @downvoter,我真的不介意投反对票,但如果您留下评论/投反对票的原因,我将不胜感激,这样我也可以学习,下次不会犯同样的错误。 @David,只要不重新分配它,您就可以修改声明为 const 的数组。
  • @AnaLizaPandac 不知道你为什么被否决,一定有人不懂 vue/javascript,因为这确实是正确的答案
【解决方案2】:

鉴于您说删除警报使其起作用,这让我想知道您是否只是在错误的位置观察值。从你给出的内容我无法确定。

请记住,Javascript 是单线程的,您的变更必须在任何其他注入 Vue 的反应性代码运行之前完成。

如果您真的希望在突变完成之前显示该值,您可能会调用Vue.nextTick(() => alert(...)),但更好的答案是在其他地方检查更新,例如在调用 getter 的计算中state.all 数组。

(顺便说一句,我发现使用console.log(...) 或vue-dev-tools 比alert() 进行任意调试要快得多。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-19
    • 2017-09-06
    • 2018-10-23
    • 2020-11-23
    • 2020-12-22
    • 2023-03-16
    • 2020-05-18
    • 2019-08-08
    相关资源
    最近更新 更多