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?
            Asked
            
        
        
            Active
            
        
            Viewed 1.2k times
        
    2 Answers
21
            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.
 
    
    
        Reinhard
        
- 1,516
- 1
- 18
- 25
- 
                    1using [lzutf8](https://www.npmjs.com/package/lzutf8) to compress the states while keeping them in the history can save us some memory storage. – Mohammad Hassany Dec 21 '21 at 15:37
7
            
            
        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).
 
    
    
        FitzFish
        
- 8,557
- 2
- 30
- 39
