我正在努力完成Vuex的基本任务,但由于某种原因它不起作用,经过广泛的搜索,我非常感谢任何帮助。
我正在尝试做什么:
使用新属性(对象)更新商店中对象的列表(对象)。
出了什么问题:
在我调度动作以从我的组件提交新对象之前(我通过mapActions访问动作),列表中任何现有对象的某些属性将使用与输入/ v模型关联的值进行更新在我的组件中。正如我的代码如下所示,我知道对象的反应性是一个问题,因此我根据文档使用Vue.set(...)
(Mutations Follow Vue's Reactivity Rules)
为什么我不认为我做的事情完全是愚蠢的......(但可能错了)
当我检查DevTools中的变异时,会按预期记录变异,当我按下“Commit”/“Commit All”时,列表中的现有对象不再响应输入中的变化。这显然是我期望发生的行为,因为该行动实际上应该将更改提交给状态。然而,为什么它不能在代码中工作,只能在devtools中工作?
我再次为可能是一个基本问题道歉,但我看到其他一些人有类似的问题,没有书面解释我们错过了什么......
初始状态
const state = {
quotes: {}
}
突变
mutations: {
[types.ADD_QUOTE] (state, payload) {
Vue.set(state.quotes, payload.id, payload)
}
}
动作
actions: {
addQuote ({ commit }, payload) {
commit(types.ADD_QUOTE, payload)
}
}
组件
<template>
<div class="quote-block">
<label>price</label>
<input type="text" v-model="quote.price">
<label>id</label>
<input type="text" v-model="quote.id">
<!-- Just displaying props below -->
<div>{{ quote.item }}</div>
<div>{{ quote.vendor }}</div>
<div>Qty: {{ quote.qty }}</div>
<button @click="addQuote(quote)">Submit quote</button>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
props: {
vendor: String,
item: String,
qty: Number
},
data () {
return {
quote: {
id: '',
price: '',
timestamp: Date.now(),
vendor: this.vendor,
item: this.item,
qty: this.qty
}
}
},
methods: {
...mapActions([
'addQuote'
])
}
}
总结一下,在devtools中,我看到id
和price
的值在我设置为state.quotes
的对象中发生变化 - 它们显然是并列的到我的组件中的quote.price
和quote.id
的v模型。只有当我在devtools中“全部提交”时,这些对象的属性才会停止变化。为什么行动中的commit
方法不能进行这些提交?
答案 0 :(得分:2)
您陷入对象引用陷阱。 引用是一个对象,它作为有效负载传递给动作。当您提交该有效负载时,它会将引用保护到您的状态。
现在组件和商店都指向同一个对象。
解决方案是将输入复制到新对象中,使用扩展运算符或Object.assign
总是一个好的做法是始终在mutator中复制有效负载(如果它是一个对象)
function(state, payload){
Vue.set(state.quotes, payload.id, {... payload });
}