我在此处和其他地方阅读了多个与此相关的类似问题,但我无法弄清楚。
我有一个带有 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_start
、runtime
、description
全部更新。
此外,这可以正常工作并更新所有内容:
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()
。搜索.showstate
的 search
属性(顺便说一句,这是错误的,你应该只在突变内部进行变异! )。请阅读下面的原因。
然后你试图触发突变。但猜猜怎么了? 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/