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

后端 未结 2 678
清歌不尽
清歌不尽 2021-01-01 02:01

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 c

相关标签:
2条回答
  • 2021-01-01 02:10

    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).

    0 讨论(0)
  • 2021-01-01 02:32

    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.

    0 讨论(0)
提交回复
热议问题