source

Vue watch 어레이에서 이전 값과 새 값이 동일하게 푸시됨

manysource 2022. 10. 15. 10:00

Vue watch 어레이에서 이전 값과 새 값이 동일하게 푸시됨

Vuex를 사용하고 있는데 다음과 같은 claims라는 모듈을 만들었습니다.

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는 돌연변이 전 값의 복사본을 보관하지 않습니다.

https://vuejs.org/v2/api/ #vm-watch

그럼 제 질문은 어떻게 하면 이 변이를 해결할 수 있을까요?

편집:

저도 한번 해봤는데Vue.set(state, state.length, generateTxData)하지만 같은 행동을 했어요

편집 2 - 임시 솔루션 - (성능 면에서 좋지 않음):

vuexfire를 사용한 솔루션에 @matthew(@Jacob Goh 덕분에)를 적응시키고 있습니다.

computed: {
  ...mapState({
    claims: state => cloneDeep(state.claims)
  })
},

이 답변은 @matthew의 매우 현명한 답변에 기초하고 있습니다.

lodash clone Deep 기능이 필요합니다.

기본적으로 다음과 같이 계산된 값을 생성합니다.

computed: {
    claimsForWatcher() {
        return _.cloneDeep(this.claims);
    }
}

새로운 값이 입력될 때마다claims는 완전히 새로운 오브젝트가 됩니다.

그렇기 때문에 여러분들이 보시면claimsForWatcher'오브젝트/어레이가 동일하기 때문에 이전 값이 새 값과 같아집니다'라는 문제가 발생하지 않습니다.

watch: {
    claimsForWatcher(oldValue, newValue) {
        // now oldValue and newValue will be 2 entirely different objects
    }
}

경고: 데이터 증가에 따른 퍼포먼스 비용 발생

상태를 새 개체에 할당할 수 있습니다.

  mutations: {
    [GENERATE_TX_SUCCESS] (state, generateTxData) {
      state = [
         ...state,
         { transaction: { ...generateTxData } }
      ]
    },
    [GENERATE_TX_ERROR] (state, generateTxError) {
      state = [
         ...state,
         { transaction: { ...generateTxError } }
      ]
    }
  }

언급URL : https://stackoverflow.com/questions/50682261/vue-watch-array-push-same-old-and-new-values