回到 Vue.js vuex 上的撤消重做状态

Going back to States like Undo Redo on Vue.js vuex

如何使用 Vuex 进行撤消/重做?我正在开发一个非常复杂的应用程序,Vue 开发工具帮助我在状态之间切换了很多,所以我希望我的应用程序具有该功能。我怎样才能做到这一点?

参见:https://vuex.vuejs.org/en/api.html

您可以轻松地使用 subscribe(handler: Function) 来注册一个函数,该函数将给定 Store 中您想要的所有状态保存在一个数组中。

然后您可以使用该数组中的任何已保存状态,方法是将它们作为参数提供给 replaceState(state: Object)

我按如下方式实现了撤消重做:

1) 为 vuex 创建一个插件

const undoRedoPlugin = (store) => {
  // initialize and save the starting stage
  undoRedoHistory.init(store);
  let firstState = cloneDeep(store.state);
  undoRedoHistory.addState(firstState);

  store.subscribe((mutation, state) => {
    // is called AFTER every mutation
    undoRedoHistory.addState(cloneDeep(state));
  });
}

2) 使用该插件

new Vuex.Store({
... 
  plugins: [undoRedoPlugin]
});

3) 在undoRedoHistory

中保存状态历史
class UndoRedoHistory {
  store;
  history = [];
  currentIndex = -1;

  init(store) {
    this.store = store;
  }

  addState(state) {
    // may be we have to remove redo steps
    if (this.currentIndex + 1 < this.history.length) {
      this.history.splice(this.currentIndex + 1);
    }
    this.history.push(state);
    this.currentIndex++;
  }

  undo() {
    const prevState = this.history[this.currentIndex - 1];
    // take a copy of the history state
    // because it would be changed during store mutations
    // what would corrupt the undo-redo-history
    // (same on redo)
    this.store.replaceState(cloneDeep(prevState));
    this.currentIndex--;
  }

  redo() {
    const nextState = this.history[this.currentIndex + 1];
    this.store.replaceState(cloneDeep(nextState));
    this.currentIndex++;
  }
}

const undoRedoHistory = new UndoRedoHistory();

4) 使用它

undoRedoHistory.undo();
...
undoRedoHistory.redo();

如果您的州规模不大,那么克隆该州是一个好方法。