Vue-select: Multiple select and Vuex

Created on 2 May 2018  路  5Comments  路  Source: sagalbot/vue-select

Got one problem, when storing value of multiple select in store.

Let's say we have store like this:

state: {
    values: null,
    options: ['a', 'b', 'c']
},
mutations: {
    setValue (state, values) {
        state.values = values;
    }
}

and somewhere in the form.vue file:

<template>
   <vue-select 
        multiple :value="$store.state.values" 
        :options="$store.state.options"
        @input="$store.state.commit('setValue', $event)"
   >
</template>

Of course that's just a simplified example. In Select.vue component you have a select method, where you have this code:

if (this.multiple && !this.mutableValue) {
    this.mutableValue = [option] //FIRST_OPTION_PICK
} else if (this.multiple) {
    this.mutableValue.push(option) //SECOND_OPTION_PICK
} else {
    this.mutableValue = option
}

At first change, when we choose a value, everything works fine. That's because FIRST_OPTION_PICK line is executed, new array is created, nothing is mutated. However, when we pick the second value, the SECOND_OPTION_PICK is executed, which just push new value to existing array. And this operation triggers Vuex error Error: [vuex] Do not mutate vuex store state outside mutation handlers.

The problem is probably in created method, where at the beginning we have this: this.mutableValue = this.value, which creates only a reference, not a copy, when the value is an array. Then in SECOND_OPTION_PICK there is array push, which mutates value array in store.

Is there any way to make "values" immutable, or it is bug that needs to be fixed in vue-select package?

Most helpful comment

I am having this problem as well. It appears to only be an issue when you have strict: true for vuex with multiple on the v-select. Here is a reproduction link https://codepen.io/CaleCrawford/pen/yEYbRP. If you add one all is good, if you add two you get the Error: [vuex] Do not mutate vuex store state outside mutation handlers. Seems like it coming from inside the vue select lib.

All 5 comments

You can handle this by moving the values into a computed value. That way you can define a getter and setter and do not need to include the input event. It could look something like this.

computed: {
    values: {
        get() {
            return this.$store.getters.values;
        },
        set(values) {
            this.$store.commit('setValue', values);
        }
    }
}

Then the component can be defined like so <vue-select v-model="values" :options="$store.state.options" multiple></vue-select>

I am having this problem as well. It appears to only be an issue when you have strict: true for vuex with multiple on the v-select. Here is a reproduction link https://codepen.io/CaleCrawford/pen/yEYbRP. If you add one all is good, if you add two you get the Error: [vuex] Do not mutate vuex store state outside mutation handlers. Seems like it coming from inside the vue select lib.

Can confirm the issue is there , and only manifests for multis.

_Strict: false_ is an unacceptable workaround in my case. I changed two lines to use non-mutating modifiers. It's still a stupid workaround that defeats the whole point of using vuex in the first place but whatever...:)

In Select.vue:

Line 829 in the select(option) method:
this.mutableValue.push(option)
Change to:
this.mutableValue = this.mutableValue.concat(option)

Line 852 in the deselect(option) method:
this.mutableValue.splice(index, 1)
Change to:
this.mutableValue = this.mutableValue.filter( a => a !== ref )

Closed with merge of #702. Will be in v3.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rudykaze picture rudykaze  路  3Comments

gilles6 picture gilles6  路  3Comments

threeaccents picture threeaccents  路  3Comments

mattWalters0 picture mattWalters0  路  3Comments

jluterek picture jluterek  路  3Comments