Storing Data with Local Storage and Vuex with the vuex-persistedstate Library

John Au-Yeung - Jan 26 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

The vuex-persistedstate library lets us add persistence to local storage of our data in our Vuex store.

In this article, we’ll look at how to use it to save data.

Installation

We can install it by running:

npm install --save vuex-persistedstate
Enter fullscreen mode Exit fullscreen mode

Also, we can install it with a script tag:

<script src="https://unpkg.com/vuex-persistedstate/dist/vuex-persistedstate.umd.js"></script>
Enter fullscreen mode Exit fullscreen mode

Then the window.createPersistedState is available for us to use.

Saving Vuex State in Local Storage

We can save our Vuex state to local storage with the createPersistedState function.

To use it, we write:

main.js

import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";
import createPersistedState from "vuex-persistedstate";

Vue.use(Vuex);
Vue.config.productionTip = false;

const store = new Vuex.Store({
  state: {
    count: 0
  },
  plugins: [createPersistedState()],
  mutations: {
    increment: (state) => state.count++,
    decrement: (state) => state.count--
  }
});
new Vue({
  store,
  render: (h) => h(App)
}).$mount("#app");
Enter fullscreen mode Exit fullscreen mode

App.vue

<template>
  <div id="app">
    <p>{{ count }}</p>
    <p>
      <button [@click](http://twitter.com/click "Twitter profile for @click")="increment">increment</button>
      <button [@click](http://twitter.com/click "Twitter profile for @click")="decrement">decrement</button>
    </p>
  </div>
</template>

<script>
export default {
  name: "App",
  computed: {
    count() {
      return this.$store.state.count;
    }
  },
  methods: {
    increment() {
      this.$store.commit("increment");
    },
    decrement() {
      this.$store.commit("decrement");
    }
  }
};
</script>
Enter fullscreen mode Exit fullscreen mode

In main.js , we registered the Vuex plugin and created the store.

The store has the count state and mutations to change it,.

Also, we added the plugin created by the createPersistedState function from the vuex-persistedstate library.

This way, we can store the store’s state in local storage.

In App.vue , we get the count state in count computed property.

And we call commit to commit the mutations for changing the count state.

Storing Vuex State as Cookies

Alternatively, we can store Vuex states as cookies. To do that, we can use vuex-persistedstate with the js-cookie library.

We install js-cookie by running:

npm i js-cookie
Enter fullscreen mode Exit fullscreen mode

In main.js , we change it to:

import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";
import createPersistedState from "vuex-persistedstate";
import Cookies from "js-cookie";

Vue.use(Vuex);
Vue.config.productionTip = false;

const store = new Vuex.Store({
  state: {
    count: 0
  },
  plugins: [
    createPersistedState({
      storage: {
        getItem: (key) => Cookies.get(key),
        setItem: (key, value) =>
          Cookies.set(key, value, { expires: 3, secure: true }),
        removeItem: (key) => Cookies.remove(key)
      }
    })
  ],
  mutations: {
    increment: (state) => state.count++,
    decrement: (state) => state.count--
  }
});
new Vue({
  store,
  render: (h) => h(App)
}).$mount("#app");
Enter fullscreen mode Exit fullscreen mode

App.vue stays the same.

We passed in an object so that we can get the data by its key with getItem .

setItem sets the data with the given key. expires is the expiry time in days. secure makes sure the cookie is only set over HTTPS.

removeItem removes an item by its key.

Secure Local Storage

We can scramble the data in local storage with the secure-ls library.

To use it, we can change main.js to:

import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";
import createPersistedState from "vuex-persistedstate";
import SecureLS from "secure-ls";
const ls = new SecureLS({ isCompression: false });
Vue.use(Vuex);
Vue.config.productionTip = false;

const store = new Vuex.Store({
  state: {
    count: 0
  },
  plugins: [
    createPersistedState({
      storage: {
        getItem: (key) => ls.get(key),
        setItem: (key, value) => ls.set(key, value),
        removeItem: (key) => ls.remove(key)
      }
    })
  ],
  mutations: {
    increment: (state) => state.count++,
    decrement: (state) => state.count--
  }
});
new Vue({
  store,
  render: (h) => h(App)
}).$mount("#app");
Enter fullscreen mode Exit fullscreen mode

We import the secure-ls library and create the ls object to let us get, set, and remove items from local storage.

Whatever is saved will be scrambled so no one can see it the browser dev console.

Conclusion

The vuex-persistedstate library is a useful library for storing Vuex state in local storage.

This way, we can keep the after we refresh the page.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .