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;
