Vue手表阵列推入相同的新旧价值 [英] Vue watch array push same old and new values
问题描述
我正在使用Vuex,并创建了一个名为Claims的模块,如下所示:
I'm using Vuex and I've created a module called claims that looks like this:
import to from 'await-to-js'
import { functions } from '@/main'
import Vue from 'vue'
const GENERATE_TX_SUCCESS = 'GENERATE_TX_SUCCESS'
const GENERATE_TX_ERROR = 'GENERATE_TX_ERROR'
export default {
state: [ ],
mutations: {
[GENERATE_TX_SUCCESS] (state, generateTxData) {
state.push({ transaction: { ...generateTxData } })
},
[GENERATE_TX_ERROR] (state, generateTxError) {
state.push({ transaction: { ...generateTxError } })
}
},
actions: {
async generateTx ({ commit }, data) {
const [generateTxError, generateTxData] = await to(functions.httpsCallable('generateTx')(data))
if (generateTxError) {
commit(GENERATE_TX_ERROR, generateTxError)
} else {
commit(GENERATE_TX_SUCCESS, generateTxData)
}
}
},
getters: { }
}
然后,在.vue组件中,我确实有一块手表:
Then, in the .vue component I do have this watch:
watch: {
claims: {
handler (newTxData, oldTxData) {
console.log(newTxData)
}
}
}
我在这里面临的问题是newTxData与oldTxData相同.
The problem I'm facing here is that newTxData is the same as oldTxData.
根据我的理解,由于这是一个推动并且可以检测到更改,因此它不是以下警告之一: https://vuejs.org/v2/guide/list.html#Caveats
From my understanding, since this is a push and it detects the change, it's not one of these caveats: https://vuejs.org/v2/guide/list.html#Caveats
所以基本上问题是这个:
So basically the problem is this one:
注意:变异(而不是替换)对象或数组时,旧值将与新值相同,因为它们引用相同的对象/数组.Vue不会保留突变前值的副本.
Note: when mutating (rather than replacing) an Object or an Array, the old value will be the same as new value because they reference the same Object/Array. Vue doesn’t keep a copy of the pre-mutate value.
https://vuejs.org/v2/api/#vm-watch
那么我的问题是:在突变中我应该如何解决呢?
Then my question is: how should I workaround this in the mutation?
修改:
我也尝试了 Vue.set(state,state.length,generateTxData)
,但行为却相同.
I tried also with Vue.set(state, state.length, generateTxData)
but got the same behaviour.
编辑2 -临时解决方案-(性能不佳):
我正在将 @matthew(感谢@Jacob Goh)调整为我的解决方案,并使用
I'm adapting @matthew (thanks to @Jacob Goh) to my solution with vuexfire:
computed: {
...mapState({
claims: state => cloneDeep(state.claims)
})
},
推荐答案
此答案基于@matthew的这个非常聪明的答案
This answer is based on this pretty smart answer by @matthew
您将需要 lodash cloneDeep 函数
基本上,创建一个像这样的计算值
Basically, create a computed value like this
computed: {
claimsForWatcher() {
return _.cloneDeep(this.claims);
}
}
发生的事情是,每当将新值推入 claims
中时, claimsForWatcher
就会成为一个全新的对象.
What happens is, everytime a new value is pushed into claims
, claimsForWatcher
will become an entirely new object.
因此,当您观看 claimsForWatcher
时,不会出现旧值与新值相同,因为它们引用相同的Object/Array"的问题.了.
Therefore, when you watch claimsForWatcher
, you won't have the problem where 'the old value will be the same as new value because they reference the same Object/Array' anymore.
watch: {
claimsForWatcher(oldValue, newValue) {
// now oldValue and newValue will be 2 entirely different objects
}
}
警告:随着数据的增长,这会带来性能成本
这篇关于Vue手表阵列推入相同的新旧价值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!