Search code examples
vue.jsvuejs2vuex

Get and edit state from a component using Vuex. ReferenceError: $store is not defined


I'm using Vuex to store some data. I'm trying to get a value stored in a state, but I don't know how to retrieve it from a component.

I want to load the value inside the data function from my component shown below. I can save some data succesfully by using this.$store.dispatch('currentUser/loginUser',this.user), but i don't know how to get it.

This is the structure of the Vuex modules:

enter image description here

The data I want to get is in loginSettings.js file. I need to retrieve the closed boolean. This is the content inside the file:

const state = {
    loginModal:{
        closed: false, // This is the value I need
    }
};
const getters = {};
const actions = {};
const mutations = {};

export default {
    namespaced: true,
    state,
    getters,
    actions,
    mutations
}

And this is the script tag inside my component.

<script>
  export default {
    data: () => ({
      dialog: this.$store.state.loginModal.closed, // This is throwing an error. The error is under this code block
      user:{
          email: "",
          password: ""
      }
    }),
    methods:{
        login(){
            this.$store.dispatch('currentUser/loginUser',this.user)
        }
    }

  }
</script>

The error: Error in data(): "ReferenceError: $store is not defined"

What is the correct way to make the component's property reactive using Vuex?


Solution

  • You forgot this so it's not looking for the $store variable on the Vue instance, but a $store variable in global scope (which is undefined). Also, with namespaced modules you need to include the module name after this.$store.state, so this.$store.state.loginSettings is the state object you're trying to access.

    However, you want to put store variables in computed, rather than data, so they're updated when they change. Data is only local state and thus it would only initially set your local state to the state in your vuex store and not be reactive.

    Thus, this should be your answer:

    computed: {
      loginModal() {
        return this.$store.state.loginSettings.loginModal
      }
    }
    
    // or
    
    computed: {
      closed() {
        return this.$store.state.loginSettings.loginModal.closed
      }
    }
    

    I would advise against putting local state (whether a component is closed or not seems specific to that component) in your vuex store.

    P.S. you can import { mapState } from 'vuex' and use it to automatically generate computed properties for you like this:

    computed: {
      ...mapState('loginSettings', ['loginModal']),
    }