You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Vuex Store状态中对象数组的新旧值?

解决Vuex数组watch时新旧值引用相同的问题

你遇到的这个问题确实是Vue响应式系统的特性——当你在Vuex里**修改(mutate)**数组/对象(比如push、splice、修改属性)时,新旧值会指向同一个引用,因为Vue不会自动保存修改前的副本。下面给你两种实用的解决方案,你可以根据场景选择:

方案一:在Vuex mutation中替换数组(推荐)

这是最符合Vue响应式设计的方式,核心思路是不修改原数组,而是创建新数组替换它。这样Vue能检测到引用变化,watch的新旧值就会是两个不同的数组,自然能拿到各自的内容。

比如你的mutation原来可能是这样修改数组的:

// 不推荐:直接修改原数组
mutations: {
  ADD_SELL_ORDER(state, newOrder) {
    state.orderBookSell.push(newOrder); // 直接修改原数组,引用不变
  }
}

改成替换数组的方式:

// 推荐:创建新数组替换原数组
mutations: {
  ADD_SELL_ORDER(state, newOrder) {
    // 用展开运算符创建新数组,添加新元素后赋值
    state.orderBookSell = [...state.orderBookSell, newOrder];
    // 或者用slice() + concat,效果一样:
    // state.orderBookSell = state.orderBookSell.concat([newOrder]);
  },
  UPDATE_SELL_ORDER(state, updatedOrder) {
    // 如果是更新数组里的某个元素,也返回新数组
    state.orderBookSell = state.orderBookSell.map(item => {
      if (item.id === updatedOrder.id) {
        return {...item, ...updatedOrder}; // 同样替换对象,不修改原对象
      }
      return item;
    });
  }
}

这样修改后,你的组件watch代码不需要改动,就能直接拿到正确的newArray和oldArray:

export default {
  name: 'O1_OrderBook',
  watch: {
    '$store.state.orderBookSell': {
      deep: true,
      handler (newArray, oldArray) {
        console.log('新数组:', newArray);
        console.log('旧数组:', oldArray); // 现在是修改前的数组副本引用
      }
    }
  },
}

方案二:在组件中手动保存旧值

如果因为性能或其他原因,必须在Vuex里修改原数组,那可以在组件里自己维护旧值的副本。具体步骤是:

  1. 在组件data里定义一个变量存储旧值
  2. 开启watch的immediate: true,初始化时保存初始值
  3. 在watch handler里,先使用保存的旧值,再更新旧值为当前新值的深拷贝

代码示例:

import _ from 'lodash'; // 可以用lodash的深拷贝,或者自己实现

export default {
  name: 'O1_OrderBook',
  data() {
    return {
      previousSellBook: []
    }
  },
  watch: {
    '$store.state.orderBookSell': {
      deep: true,
      immediate: true, // 初始化时触发一次,保存初始值
      handler (newArray) {
        // 此时previousSellBook就是修改前的旧值
        console.log('旧数组:', this.previousSellBook);
        console.log('新数组:', newArray);
        
        // 更新旧值为当前数组的深拷贝,下次触发时用
        this.previousSellBook = _.cloneDeep(newArray);
        // 如果不用lodash,也可以用JSON.parse(JSON.stringify(newArray)),但注意不能处理函数、Symbol等类型
        // this.previousSellBook = JSON.parse(JSON.stringify(newArray));
      }
    }
  },
}

注意:这种方法需要自己处理深拷贝,如果数组里的对象层级比较深,一定要用可靠的深拷贝方式,不然还是会出现引用共享的问题。

内容的提问来源于stack exchange,提问作者Matthew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:42:09