javascript - 如何在 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: {}
}
应用(保存主 vuex 树中的更改):
state: {
animals: [
dogs: [
{ breed: 'chihuahua' },
{ breed: 'dachshund' },
]
],
tryout: {}
}
有什么好的解决方案可以深度克隆状态,对克隆进行更改,然后丢弃或应用更改?这里的示例非常基础,解决方案必须使用更复杂的对象/树。
编辑 1:
有一个名为vuex-undo-redo的库,它基本上记录突变,但有一些问题。在另一个 Stack Overflow 主题中,回到 Vue.js 上的 Undo Redo 等状态,vuex建议使用 vuex 函数replaceState(state)
。
解决方案
您可以使用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} );
}
这会将当前状态与您选择的对象(如本例中的动物)合并。
推荐阅读
- c# - 有同名方法时如何注册EventHandler
- mongodb - Mongodb 连接尝试失败:SSLHandshakeFailed:SSL 对等证书验证失败:自签名证书
- javascript - fullcalendar 在超过 10k 个事件后停止显示事件
- opos - 如何在远程会话中使用 POS for .Net 打开连接到本地计算机的现金抽屉
- vb.net - 在 VB.NET 中延迟从另一个按钮调用一个按钮
- php - 从控制器获取单个值以在 Laravel 中查看
- google-custom-search - 谷歌自定义搜索引擎 - 仅在特定链接下搜索
- c# - 用新数字替换第一个左括号和数字
- regex - 使用正则表达式的“对象变量或未设置块变量”
- javascript - 如何使用javascript计算两个时间戳之间的差异