SheppardPL
SheppardPL

Reputation: 85

Storing JavaScript Object and mutating it in Vuex - conception

Lets say I have JavaScript object class like below:

class Car {
  var engineTurnedOn = false;
  ...

  public turnEngineOn() {
     engineTurnedOn = true
  }
}

Now I want to turn engine on. Should I create an action called turnEngineOn which will trigger mutation, which will trigger method 'turnEngineOn' or just call this method on an object directly? In the second case store would be only responsible for management an array of Cars instead of manipulating cars.

Case 1:

//actions
turnEngineOn = ({commit}, car) => {
   dispatch('turnEngineOn', car);
}

//mutation
turnEngineOn = (state, car) => {
  car.turnEngineOn()
}

Case 2: car.turnEngineOn() //outside actions

or maybe I do not need a JavaScript Object?

Regards

Upvotes: 0

Views: 875

Answers (1)

Reşit Körsu
Reşit Körsu

Reputation: 598

The turnEngineOn method is a component method so it shouldn't be in the vuex to execute mutation at least. Vuex actions are for asynchronous calls like http requests. Actions can commit mutations after asynchrounous call and mutations mutate the state thats right.

I think you are using Typscript thats why you are using javascript class syntax? If not I recommend using Typescript or not using class syntax.

Mutations should be the only way to change your vuex state, whether you can commit a mutation directly from a component to change the state or you can dispatch an action to commit a mutation. I am using only dispatch in components and not using commits to state change but thats just an opinion as i see from community, some people commits from components. So your code should be like this:

// Car Component...

class Car {
    // var isEngineOn = true, you don't need this in here if you want to use vuex state
    // You need Vue's computed property to reach an element in the vuex store
    get isEngineOn () {
        return this.$store.getters.isEngineOn
    }
    .
    .
    .
    public toggleEngine () {
        this.$store.dispatch('toggleEngine') // You don't need payload in this one
        // You can commit directly like 'this.$store.commit('toggleEngine') if you don't need an action here
    }
}

Now you can bind the method to a button or whatever you like to toggle the car engine.

// You need to define the engine variable in your vuex state...
const state = {
...
    isEngineOn: true,
...
}

// Vuex actions...
toggleEngine ({ commit, state }) {
    commit('toggleEngine')
}

// Vuex mutations...
toggleEngine (state) {
    state.isEngineOn = !state.isEngineOn // makes the variable true if false and vice versa
}

// Vuex getters...
isEngineOn (state) {
    return state.isEngineOn
}

Now you can change your state from your component and use your state variable in your template with your computed property.

Check out docs for further details, and this graph started to make sense after understanding this logic:P. https://github.com/vuejs/vuex

Upvotes: 1

Related Questions