在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: {}
}
应用(保存主vuex树中的更改):
state: {
animals: [
dogs: [
{ breed: 'chihuahua' },
{ breed: 'dachshund' },
]
],
tryout: {}
}
什么是深度克隆状态,在克隆上进行更改,然后又放弃更改或应用更改的好的解决方案? 这里的示例非常基础,该解决方案必须适用于更复杂的对象/树。
编辑1:
有一个名为vuex-undo-redo的库,它基本上记录了突变,但是存在一些问题。在另一个堆栈溢出主题Going back to States like Undo Redo on Vue.js vuex中,建议使用vuex函数replaceState(state)
。
答案 0 :(得分:2)
您可以将JSON.stringify
和JSON.parse
与replaceState
一起使用。
在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} );
}
这会将当前状态与您选择的对象(在本例中为动物)合并。