0
votes

I have been trying to learn Vuex recently so that my data and unfinished form data are not lost when I navigate between routes. In Vuex's page there is a simple management example about incrementing and decrementing a value but I have trouble adapting this example to what I need. I have a simple component which takes username and password from the user. Since I will use this method everywhere in my project, I want to use this method in checkboxes, select elements and generally all form elements. Let's say the user typed for the username input and left the password one and navigate between different routes, components and came back to the first component. I want username input field is to be filled with the one the user typed earlier. I think I need two way data binding because I also do some validations for every input element in my project and they are all connected with a unique data with v-model.

I tried to create the store.js file and and a state inside of it. When I declare a state as username and set it to something static like "Jason", I am able to use it in my component as this.$store.state.username But here is my question; How do I set the

state : {
 username: 'Jason'
}

something dynamic so that it changes everytime the username input field is typed. Here is my username input;

<input v-model="userData.username" type="text" />

data() {
      return {
        userData: {
          username: "",
        },
      };
    },

When the user types something, username is updated in the data. I want this to change in the state in Vuex, so even if the route or component has changed, I will be able to use that data when I return. I am not sure if I understand the usage correctly. Am I missing something? Can you help me? Thanks in advance!

Store.js

state:{
    cloud_user:""
 },
 mutations:{
    set_userName(state, val){
      state.cloud_user = val
    }
 }

Computed

computed: {
  set_username:{
    set(val){
      this.$store.commit("set_username", val)
    },
    get(){
      return this.$store.state.username
    }
  }
}
 

Currently I am having the following error

[Vue warn]: Method "computed" has type "object" in the component definition. Did you reference the function correctly?

And plus, have this error too;

[Vue warn]: Property or method "set_username" is not defined on the instance but referenced during render.
1

1 Answers

2
votes

Actually you don't need to use the data() prop. But you need use the computed and you should use the setter.

template

<input v-model="set_userName" type="text" />

script

<script>
  export default {
    computed: {
      set_username:{
        set(val){

        },
        get(){
          
        }
      }
    }
  }
</script>

vuex.store

 state:{
    userName:""
 },
 mutations:{
    set_userName(state, val){
      state.userName = val
    }
 }

And what we have done. We created computed property, then set the value to vuex AND get the newly setted data from vuex.

The key point lies in the mutations part. You are setting the current value by set(val) and commiting it to the mutation as val in the set_userName(state, val), then giving that val to the state.

UPDATED

Also adding a more proper way to mutate a state. Not by directly from the setter, but by actions.

Right below the mutations:{} create actions.

 state:{
    userName:""
 },
 mutations:{
    set_userName(state, val){
      state.userName = val
    }
 },
 actions:{
    PATCH_CURRENT_VALUE({commit}, payload){
      this.commit("set_userName", payload)
    }
 }

Now you should change the computed:{}

 computed: {
      set_username:{
        set(val){
           this.$store.dispatch("PATCH_CURRENT_VALUE", val)
        },
        get(){
           return this.$store.state.username
        }
      }
  }