Shawn Wildermuth

Creating a Vuex Plugin


VueIf you're building larger scale Vue objects and you're not using Vuex to centralize your state, please stop and go learn Vuex. Really. For those of you still here, sometimes it's helpful to be able to monitor state changes to perform other tasks. For example, to send messages or communicate with servers that aren't about state (e.g. SignalR is a good example). That's where Vuex plugins come in. A Vuex plugin is a simple function that is called once during the setup of a Vuex store. Typically you'd just create the function/arrow function taking an instance of the store:

export default store => {
};

Inside the function, you just want to subscribe to changes to the store as you need. An easy way to think about this is to use subscribe to a mutation:

export default store => {
  store.subscribe((mutation, state) => {
    if (mutation.type === "setError") {
      // Alert someone
      alert("Error occurred!");
    }
  });
};

The mutation that is passed in has a "type" and a "payload". With these properties of the mutation you can determine what to do. For example, the above example just pops up an alert (a really bad thing to do btw) when setError mutation is called. setError is a mutation in a store:

  mutations: {
    ...
    setError(state, msg) {
      state.error = msg;
      if (msg) console.log(`Error: ${msg}`);
    }
  },

Additionally, if you're using 3.1.0 or later of Vuex, they've added subscribing to actions too (subscribeAction):

export default store => {
  store.subscribe((mutation, state) => {
    if (mutation.type === "setError") {
      alert("Call removed!");
    }
  });

  store.subscribeAction({
    after: (action, state) => {
      if (action.type === "load") {
        alert("loading data");
      }
    }
  });
};

The subscribeAction works very similarly to the subscribe, except it's sending a type and payload about the action being called, not the mutation.

Once you have the plugin defined, it's as simple as registering it with your store. You do this by adding it to an array of plugins in your store:

...
import alertPlugin from "./alertplugin";

Vue.use(Vuex);

var store = new Vuex.Store({
  strict: true,
  plugins: [alertPlugin],
  state: {
    calls: [],
    error: ""
  },
...

You can use this technique in your own apps that use Vuex for state. If you'd like to see the full example, it's here on github:

https://github.com/shawnwildermuth/wilderexamples/tree/master/CallCenter-Vuex

What do you think?