undo-redo 实现思路
- 用一个数组保存栈,保存每一步的操作
- 需要一个指针 currentIndex: 0
- onChange,数组 push值,更新指针 index++;
- undo回退之后,再执行新的操作,需要清除当前下标之后所有的历史数据
- undo, index—;
- redo, index++;
- 监听键盘事件,判断 undo ctrl+z 和 redo ctrl+y 快捷键
- 从E回退到C ,然后执行了新的操作F,那么D E 需要从记录队列中删除,F加入到C之后
- F之后回退到C,还能够再 redo到F
- 队列达到最大值之后,每从队尾加一个,就需要从队首剔除一个
2个栈实现
用 undo,和 redo栈实现
https://blog.csdn.net/sawa123/article/details/121821025
import { cloneDeep } from 'lodash';
import { useModel } from 'umi';
// 最大回退操作步骤
const maxStep = 60;
const undoQueue = [];
let redoQueue = [];
function useUndo() {
const { components, setComponents } = useModel('visualPage');
const saveSnap = () => {
const snap = cloneDeep(components);
if (undoQueue.length >= maxStep) {
undoQueue.shift();
}
undoQueue.push(snap);
// console.log('queue', undoQueue, redoQueue);
// 注意!!每次执行命令时清空重做栈
redoQueue = [];
};
const undo = () => {
const snap = cloneDeep(components);
const c = cloneDeep(undoQueue[undoQueue.length - 1]);
setComponents(c);
redoQueue.push(snap);
undoQueue.pop();
};
const redo = () => {
const snap = cloneDeep(components);
const c = cloneDeep(redoQueue[redoQueue.length - 1]);
setComponents(c);
undoQueue.push(snap);
redoQueue.pop();
};
return {
saveSnap,
undo,
redo,
undoQueue,
redoQueue,
};
};
export default useUndo;