javascript - 等待后的 Vuex 提交不会更新状态

标签 javascript vue.js async-await vuex

我在此处和其他地方阅读了多个与此相关的类似问题,但我无法弄清楚。

我有一个带有 mapGetters 的表单和应根据 Vuex 状态更新的输入值:

    ...mapGetters({
      show: "getShow"
    }),

示例表单输入(我正在使用 Bootstrap Vue):

      <b-form-input
        id="runtime"
        name="runtime"
        type="text"
        size="sm"
        v-model="show.runtime"
        placeholder="Runtime"
      ></b-form-input>

然后我在表单组件上有这个方法:

    async searchOnDB() {
      var showId = this.show.showId;
      if (!showId) {
        alert("Please enter a showId");
        return;
      }
      try {
        await this.$store.dispatch("searchShowOnDB", showId);
      } catch (ex) {
        console.log(ex);
        alert("error searching on DB");
      }
    },

以及商店中的此操作:

    async searchShowOnDB({ commit, rootState }, showId) {
      var response = await SearchAPI.searchShowOnDB(showId);
      var show = {
        show_start: response.data.data.first_aired,
        runtime: response.data.data.runtime,
        description: response.data.data.overview
      };
      //I'm updating the object since it could already contain something
      var new_show = Object.assign(rootState.shows.show, show);
      commit("setShow", new_show);
    }

突变:

    setShow(state, show) {
      Vue.set(state, "show", show);
    }

搜索API:

export default {
    searchShowOnDB: function (showId) {
        return axios.get('/search/?id=' + showId);
    },
}

一切正常,API调用被执行,我什至可以在Vue Devtools中看到Vuex更新状态,但表单没有更新。 一旦我在输入字段中写入内容或在 Vue Devtools 中点击 commit,表单字段 show_startruntimedescription 全部更新。

此外,这可以正常工作并更新所有内容:

    async searchShowOnDB({ commit, rootState }, showId) {
      var show = {
        show_start: "2010-03-12",
        runtime: 60,
        description: "something"
      };
      //I'm updating the object since it could already contain something
      var new_show = Object.assign(rootState.shows.show, show);
      commit("setShow", new_show);
    }

我不知道还能做什么,我尝试显式解决 Promises,删除 async/await 并使用 axios.get(...).then(...),移动周围的东西......似乎没有任何作用。

最佳答案

/modules/search.js 的第 15 行,您在 rootState 上使用 Object.assign()。搜索.show。这会改变 statesearch 属性(顺便说一句,这是错误的,你应该只在突变内部进行变异! )。请阅读下面的原因。

然后你试图触发突变。但猜猜怎么了? Vue 认为它是相同的值,因此不会通知任何组件,因为没有更改。这就是为什么你永远不要在突变之外进行突变!

因此,无需将值分配给操作中的状态,只需提交新节目(将 15-16 行替换为:

 commit('setShow', show);

在这里查看:https://codesandbox.io/s/sharp-hooks-kplp7?file=/src/modules/search.js

这将完全用 show 替换 state.show。如果您只想将响应合并到当前 state.show 中(以保留添加到当前 show 中的一些自定义内容),您可以传播 state 的内容.show 并用 show 的内容覆盖:

commit("setShow", { ...rootState.search.show, ...show });

另请注意,您的突变中不需要 Vue.set() 。任何突变的第一个参数都有 state,这就是当前模块的 state。所以只需分配state.show = show

最后一点:当你的 vuex 变得更大时,你可能想要 namespace您的模块,以避免任何名称冲突。

关于javascript - 等待后的 Vuex 提交不会更新状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61504056/

相关文章:

c# - 在 async/await 中使用 ThreadStatic 变量

javascript - 取消框架上的导航?

javascript - 我如何通过使用javascript单击asp文本字段来检查单选按钮

HTML 按钮不能正确显示在列表项旁边

javascript - await 函数返回一个 promise,即使条件为 false 也返回 true | react 功能组件

rust - 如何等待第一个k future ?

javascript - div 在 ie 中为 null,但在 mozilla 和 opera 中为 null

javascript - 删除套接字前是否需要解除绑定(bind)回调?

vue.js - 在 Vuetify 规则定义中传递额外参数

vue.js - 如何在 Vuetify 中将内容对齐到 v-card 组件的中心?