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

2019-04-03 01:47发布

How do I make undo / redo using Vuex? I am working on a pretty complex app and Vue dev tools helped me a lot to switch between state, so I want that feature on my app. How can I achieve this?

2条回答
Bombasti
2楼-- · 2019-04-03 02:35

See: https://vuex.vuejs.org/en/api.html

You can easely use subscribe(handler: Function) to register a function that keeps all the states you want from a given Store in an array.

Then you can use any of the saved state in that array by giving them as argument to replaceState(state: Object).

查看更多
对你真心纯属浪费
3楼-- · 2019-04-03 02:40

I've implemented undo-redo as follows:

1) create a plugin for 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) use that plugin

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

3) save a history of the states in 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) use it

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

If your state is not huge in size than cloning that states is a good approach.

查看更多
登录 后发表回答