Javascript Vuex:处理复杂对象和状态更改函数

Javascript Vuex:处理复杂对象和状态更改函数,javascript,vue.js,vuex,Javascript,Vue.js,Vuex,假设我使用的是一个与Machine对象一起工作的外部API。您可以使用createMachine创建一个Machine,它将为您提供一个具有多个嵌套属性的复杂对象,以及一组用于改变该对象状态的函数。该API提供例如:loadMemory、sleep、connectDevice。(想象一下类似的情况,这只是一个例子) 我想保存一个全局VuexMachine对象,因此我有一个操作来分派初始创建并存储返回的对象,如下所示: actions: { createChannel({ commit, stat

假设我使用的是一个与
Machine
对象一起工作的外部API。您可以使用
createMachine
创建一个
Machine
,它将为您提供一个具有多个嵌套属性的复杂对象,以及一组用于改变该对象状态的函数。该API提供例如:
loadMemory
sleep
connectDevice
。(想象一下类似的情况,这只是一个例子)

我想保存一个全局Vuex
Machine
对象,因此我有一个操作来分派初始创建并存储返回的对象,如下所示:

actions: {
createChannel({ commit, state }, params) {
      m.createMachine(params).then(
        function (newMachine) {
          commit('setMachine', newMachine);
        }
      ).catch(err => { console.error("Error"); } )
    }
}
在这种情况下,突变非常简单:

  setMachine(state, machine) {
      state.machine = machine;
    }
现在为“Machine”对象设置了API,正如我们所知,有一系列状态修改调用——我们不知道它们更改了哪些特定字段。 当它们修改状态时,我想使用它们来影响Vuex存储中的全局
机器
对象,我想将它们包装成动作

行动可能需要

this.state.machine.loadMemory(mem.addr)

但是如果这个调用本身修改了
机器
对象,我如何提交新状态?我是否应该克隆旧对象,应用状态更改方法并替换该对象

我知道克隆不是一件容易的事


谢谢

您可以重新装载复杂对象。根据示例,突变可能是:

loadMemory(state, newAddr) {
  const { machine } = state;

  state.machine = {
    ...machine, // set all machine's properties
    addr: newAddr,
  };
}
它适用于任何级别的嵌套对象。另一个例子:

loadMemory(state, newValue) {
  const { machine } = state;
  const { machineObjProp } = machine; 

  state.machine = {
    ...machine, // set all machine's properties
    machineObjProp: {
       ...machineObjProp, // set all machineObjProp's properties
       value: newValue,
    },
  };
}
一种方法是使用lodash,它将复制对象的应用程序属性和方法

import _ from lodash

this.state.machine.loadMemory(mem.addr)
const copyMachine = _.cloneDeep(this.state.machine)
this.$store.commit('setMachine', copyMachine)