Vue手表阵列推入相同的新旧价值 [英] Vue watch array push same old and new values

查看:47
本文介绍了Vue手表阵列推入相同的新旧价值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆