Search code examples
vue.jslocal-storagestatevuex

How to save "state" variables to the browser localStorage using Vue.js + Vuex (createStore)


I am trying to load (using mounted()) and save (with the watch: {...} method) to / from the localStorage.

The two variables i am trying to save to the localstorage are 'categories' and 'locations'.

I just cannot get it triggered for some reason. I have never done this using vue.js/vuex.

all examples I have found use the data: {} object in "regular" components. In my example I am trying to load and save to the state variables. Please help. I have pasted the whole vuex createStore object (project/src/store/index.js):

import { createStore } from 'vuex'

export default createStore({
    state: {
        categories: [ "Food", "Bars", "Parks"],
        locations: [],
    },
    mutations: {
        addCategory(state, newCategory) {
            state.categories.push(newCategory)
        }, 
        removeCategory(state, i) {
            state.categories.splice(i, 1);
        }, 
        saveCategory(state, data) {
            state.categories[data.item] = data.text
        }, 
        addLocation(state, data) {
            state.locations.push(data)
        },
        deleteLocation(state, i) {
            state.locations.splice(i, 1);
        }, 
        saveLocation(state, data) {
            state.locations[data.index].categories = data.item
        },

    },
    watch:{
        categories(newCategories) {
            console.log(newCategories)
            localStorage.categories = JSON.stringify(newCategories)
        }, 
        locations(newLocations) {
            console.log(newLocations)
            localStorage.locations = JSON.stringify(newLocations)
        }
    },
    actions: {
    },
    modules: {
    }, 
    mounted() {
        console.log(localStorage.categories)
        console.log(localStorage.locations)
        if (localStorage.categories) {
            this.categories = JSON.parse(localStorage.categories)
            if (localStorage.locations) 
                this.locations = JSON.parse(localStorage.locations)
        }

    }
})

Edit:

tried:

"state.categories" (newCategories) {
    console.log(newCategories)
    localStorage.categories = JSON.stringify(newCategories)
}, 
"state.locations" (newLocations) {
    console.log(newLocations)
    localStorage.locations = JSON.stringify(newLocations)
}

no errors but doesn't work.


Solution

  • Following the link with the great explanation: https://www.mikestreety.co.uk/blog/vue-js-using-localstorage-with-the-vuex-store/

    in my /project/src/main.js file:

    store.subscribe( (mutation, state) => {
        localStorage.setItem('categories', JSON.stringify(state.categories));  
        localStorage.setItem('locations', JSON.stringify(state.locations));  
    })
    

    in my /project/src/App.vue file I added the following (although I'm pretty sure using "mounted()" will work as well:

    beforeMount() {
        this.$store.commit('initialiseVars')
    },  
    

    and added a mutation method to /project/src/store/index.js:

    initialiseVars(state) {
        if (localStorage.getItem('categories')) {
            state.categories = JSON.parse(localStorage.categories)
            if (localStorage.getItem('locations')) 
                state.locations = JSON.parse(localStorage.locations)
        }
    }