Vuex中如何深度克隆状态和回滚?

How to deep clone the state and roll back in Vuex?

在 Vuex 中,我想拍摄树中对象 属性 的快照/克隆,修改它,然后可能回滚到之前的快照。

背景:
在应用程序中,用户可以在应用之前尝试某些更改。应用更改时,它们应该影响主 vuex 树。用户也可以点击 «取消» 放弃更改并返回到之前的状态。

示例:

state: {
  tryout: {},
  animals: [
    dogs: [
      { breed: 'poodle' },
      { breed: 'dachshund' },
    ]
  ]
}

用户进入 »试用« 模式并将一个品种从 poodle 更改为 chihuahua。然后她决定放弃更改或应用它们。

state: {
  animals: [
    dogs: [
      { breed: 'poodle' },
      { breed: 'dachshund' },
    ]
  ],
  tryout: {
    animals: [
      dogs: [
        { breed: 'chihuahua' },
        { breed: 'dachshund' },
      ]
    ]
  }
}

丢弃(回滚到之前的状态):

state: {
  animals: [
    dogs: [
      { breed: 'poodle' },
      { breed: 'dachshund' },
    ]
  ],
  tryout: {}
}

Apply(保存主 vuex 树中的更改):

state: {
  animals: [
    dogs: [
      { breed: 'chihuahua' },
      { breed: 'dachshund' },
    ]
  ],
  tryout: {}
}

深度克隆状态、对克隆进行更改,然后放弃更改或应用更改的好的解决方案是什么? 这里的示例非常基础,解决方案必须适用于更复杂的对象/树。

编辑 1:
有个库叫vuex-undo-redo, which basically logs mutations, but has some problems. In another Stack Overflow topic 推荐使用vuex函数replaceState(state).

您可以将 JSON.stringifyJSON.parsereplaceState 一起使用。

在 vuex 中:

const undoStates = [];

// save state
undoStates.push(JSON.stringify(state));

// call state (remove from stack)
if (undoStates.length > 0) {
  this.replaceState(JSON.parse(undoStates.pop()));
}

这将创建整个状态的副本,但您也可以使用商店的一部分:

const animalStates = [];

// save state
animalStates.push(JSON.stringify(state.animals));

// call state (remove from stack)
if (animalStates.length > 0) {
  let animals = JSON.parse(animalStates.pop());
  this.replaceState({...state, animals} );
}

这会将当前状态与您选择的对象(在本例中为动物)合并。