Vue watch array выдвигает те же старые и новые значения - PullRequest
0 голосов
/ 04 июня 2018

Я использую Vuex, и я создал модуль под названием утверждений, который выглядит следующим образом:

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 - временное решение - (плохая производительность):

Я адаптирую @ Мэттью (благодаря @Jacob Goh) к моему решению с vuexfire :

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

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Этот ответ основан на этот довольно умный ответ @ 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
    }
}

Предупреждение: это связано с затратами на производительность по мере увеличения ваших данных

0 голосов
/ 04 июня 2018

Вы можете назначить состояние для нового объекта:

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