我正在使用Vuex,我创建了一个名为claim的模块,如下所示:
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组件中,我确实有这个手表:
watch: {
claims: {
handler (newTxData, oldTxData) {
console.log(newTxData)
}
}
}
我面临的问题是newTxData与oldTxData相同。
根据我的理解,由于这是推动并且它检测到变化,因此不是其中一个警告:https://vuejs.org/v2/guide/list.html#Caveats
所以问题基本上就是这个问题:
注意:在变异(而不是替换)对象或数组时,旧值将与新值相同,因为它们引用相同的对象/数组。 Vue没有保留pre-mutate值的副本。
https://vuejs.org/v2/api/#vm-watch
然后我的问题是:我应该如何在变异中解决这个问题?
修改:
我也试过了Vue.set(state, state.length, generateTxData)
,但也有同样的行为。
编辑2 - 临时解决方案 - (性能不佳):
我正在使用@matthew (thanks to @Jacob Goh):
调整vuexfire到我的解决方案computed: {
...mapState({
claims: state => cloneDeep(state.claims)
})
},
答案 0 :(得分:0)
此答案基于this pretty smart answer by @matthew
您需要lodash cloneDeep功能
基本上,创建一个像这样的计算值
computed: {
claimsForWatcher() {
return _.cloneDeep(this.claims);
}
}
每当新值被推送到claims
时, claimsForWatcher
将成为一个全新的对象。
因此,当您观看claimsForWatcher
时,您将不会遇到'旧值与新值相同的问题,因为它们再次引用相同的对象/数组'
watch: {
claimsForWatcher(oldValue, newValue) {
// now oldValue and newValue will be 2 entirely different objects
}
}
警告:随着您的数据越来越大,这会带来性能成本
答案 1 :(得分:-1)
You can assign state to a new object:
mutations: {
[GENERATE_TX_SUCCESS] (state, generateTxData) {
state = [
...state,
{ transaction: { ...generateTxData } }
]
},
[GENERATE_TX_ERROR] (state, generateTxError) {
state = [
...state,
{ transaction: { ...generateTxError } }
]
}
}