Vuex Plugins

Vuex Plugins

A Vuex plugin is simply a function that receives the store as the only argument and let’s you peek into the vuex store

Why Plugins?

Monitor state changes to perform other tasks that are not state management specific

e.g. DB Calls, API Fetches etc

import Vue from "vue";
import Vuex from "vuex";
import myPlugin from "./plugins/my-plugin";

Vue.use(Vuex);

export default new Vuex.Store({
  plugins: [ myPlugin ],
  state: {
    machineName: "Wash Bucket",
    lastServiced: new Date()
  },
  getters: { ... },
  actions: {
    serviceMachine({ commit }) {
      commit(updateServiceDate, new Date())
    }
  },
  mutations: {
    updateServiceDate(state, payload) {
      state.lastServiced = payload
    }
  }
});

store.js

const myPlugin = store => {
  // called when the store is initialized
  store.subscribe((mutation, state) => {
    // called after every mutation.
    console.log(mutation.type)
    console.log(mutation.payload)
  })
}

./plugins/my-plugin

store.js

const myPlugin = store => {
  // called when the store is initialized
  store.subscribe((mutation, state) => {
    // called after every mutation
    
    // print `updateServiceDate` mutation
    console.log(mutation.type)
    
    // print `new Date()` payload
    console.log(mutation.payload)
  })
}

./plugins/my-plugin

import Vue from "vue";
import Vuex from "vuex";
import myPlugin from "./plugins/my-plugin";

Vue.use(Vuex);

export default new Vuex.Store({
  plugins: [myPlugin],
  state: {
    machineName: "Wash Bucket",
    lastServiced: new Date()
  },
  getters: { ... },
  actions: {
    serviceMachine({ commit }) {
      commit(updateServiceDate, new Date())
    }
  },
  mutations: {
    updateServiceDate(state, payload) {
      state.lastServiced = payload
    }
  }
});

Vuex Plugins

access store

const myPlugin = store => {
  // called when the store is initialized
  store.subscribe((mutation, state) => {
    // called after every mutation.
    console.log(mutation.type)
    console.log(mutation.payload)
  })
}

Vuex Plugins

subscribe to mutation

const myPlugin = store => {
  // called when the store is initialized
  store.subscribe((mutation, state) => {
    // called after every mutation.
    console.log(mutation.type)
    console.log(mutation.payload)
  })
}
const myPlugin = store => {
  // called when the store is initialized
  store.subscribe((mutation, state) => {
    // called after every mutation.
    console.log(mutation.type)
    console.log(mutation.payload)
  })
}

Vuex Plugins

access state

Vuex Plugins

access mutation properties

const myPlugin = store => {
  // called when the store is initialized
  store.subscribe((mutation, state) => {
    // called after every mutation.
    console.log(mutation.type)
    console.log(mutation.payload)
  })
}

Serviced

Serviced

Serviced

Database,

API,

localStorage,

...

Vending Machine Service Notifier

const persistServicedDatePlugin = store => {
  store.subscribe((mutation, state) => {
    ...
  });
};

export default persistServicedDatePlugin;

./plugins/persist-serviced-date.js

store.subscribe((mutation, state)) => {
  ...
})

subscribe to mutation

const persistServicedDatePlugin = store => {
  store.subscribe((mutation, state) => {
    if (mutation.type === "updateServiceDate") {
      // do some things //
    }
  });
};

export default persistServicedDatePlugin;

./plugins/persist-serviced-date.js

store.subscribe((mutation, state)) => {
  // ping external API or DB //
 console.log(mutation.type)
 console.log(mutation.payload)
})

identify mutation type and payload

const persistTime = 24 * 60 * 60 * 1000; // 1 day

const persistServicedStatePlugin = store => {
  store.subscribe((mutation, state) => {
    if (mutation.type === "updateServiceDate") {
      let record = {
        time: state.lastServiced.toLocaleString("default", {
          hour: "2-digit",
          minute: "2-digit",
          second: "2-digit",
          timeZoneName: "short"
        }),
        persistFor: new Date().getTime() + persistTime
      };
      try {
        window.localStorage.setItem("last_serviced", JSON.stringify(record));
      } catch (e) {
        throw e;
      }
    }
  });
};

export default persistDataPlugin;

./plugins/persist-serviced-date.js

Exercise Time!

Let's create our first Vuex Plugin `persistState`

[step-0]

https://github.com/shortdiv/vuex-plugin

Vuex Plugins

Vuex Plugins

const myPlugin = store => {
  // called when the store is initialized
  store.subscribeAction((action, state) => {
    // called after every action //
    console.log(action.type)
    console.log(action.payload)
  })
}

subscribe to action

Vuex Plugins

access action properties

Vuex Plugins

const myPlugin = store => {
  // called when the store is initialized
  store.subscribeAction((action, state) => {
    // called after every action //
    console.log(action.type)
    console.log(action.payload)
  })
}

Exercise Time!

Let's modify to use subscribeAction in our Vuex Plugin `persistState`

[step-1]

https://github.com/shortdiv/vuex-plugin

Vuex Plugins

Vuex Plugins

const myPlugin = store => {
  // called when the store is initialized
  store.subscribeAction({
    before: (action, state) => {
      console.log(`before action ${action.type}`)
    },
    after: (action, state) => {
      console.log(`after action ${action.type}`)
    }
  })
}

access action before or after dispatch

previousServiceDate

Database,

API,

localStorage,

...

recentServiceDate

serviceDateFrequency

Exercise Time!

Modify to use subscribeAction (before/after) that listen for action change and register the frequency change

[step-2]

https://github.com/shortdiv/vuex-plugin

Vuex Plugins

By shortdiv

Vuex Plugins

  • 705