Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuex Mutations and Airbnb eslint

Tags:

vue.js

vuex

I am unsing Airbnb Eslint on my Vuejs project (using Vue-cli). And one of the rules is no-param-reassign. In order to control the state (using Vuex), one must use mutations/ actions:

Rules conflict

mutations: {
    increase: (state) => {
        state.counter++;
    }
}

After changes according to rules

mutations: {
    increase: (state) => {
        const thisState = state;
        thisState.coutner++;
    }
}

Is there a better way to write the statement above and not breaking eslint rules?

Solution (thanks to Cobaltway's answer)

Add 'state' to the ignorePropertyModificationsFor to the rules.

like image 602
Duy Anh Avatar asked Jun 20 '17 15:06

Duy Anh


2 Answers

No, sorry.

Since a Vuex store's state is made reactive by Vue, when we mutate the state, Vue components observing the state will update automatically. This also means Vuex mutations are subject to the same reactivity caveats when working with plain Vue [...]

Source: https://vuex.vuejs.org/en/mutations.html

It does mean that you must mutate the parameter to get any change into your actual state. The only solution there is to turn off that rule.

Addendum:

I may have a better solution. Note that this is the actual rule as enforced by their ESLint:

'no-param-reassign': ['error', {
  props: true,
  ignorePropertyModificationsFor: [
    'acc', // for reduce accumulators
    'e', // for e.returnvalue
    'ctx', // for Koa routing
    'req', // for Express requests
    'request', // for Express requests
    'res', // for Express responses
    'response', // for Express responses
    '$scope', // for Angular 1 scopes
  ]
}],

You may add 'state' to the ignorePropertyModificationsFor array, so you won't encounter error when modifying your state properties.

like image 50
FitzFish Avatar answered Oct 13 '22 15:10

FitzFish


Alternative: you can use Vue.set.

Vue.set uses the same reactiveSetter function (Reference).

For example:

import Vue from 'vue';

const state = () => ({ counter: 0 });

const mutations = {
  increase(states) {
    Vue.set(states, 'counter', states.counter + 1);
  },
};

Note:

  • I use variable name states rather than state on function increase on purpose, because variable state may be defined in upper scope (like my example above). If not rename first mutations's argument to "states" (or other name), it breaks rule no-shadow.
like image 43
andreyunugro Avatar answered Oct 13 '22 15:10

andreyunugro