Home > Mobile >  Select not rendering new :value when changing options dynamically with vuejs
Select not rendering new :value when changing options dynamically with vuejs

Time:11-03

I've created a small jsfiddle which explains the error and how to reproduce it here: https://jsfiddle.net/4Leu9a6x/57/

I have a select on which I use @change and :value to update and show the value. I know I could use v-model but my app is rather complex so this is the only way to do it currently.

The problems appears when I change the options dynamically. As soon as I change them the value of the select (the one the user sees) is not the same as the real value (saved in data by vue). Even though I do have :value.

I don't understand why it doesn't show a gray select (with nothing selected) when :value is not inside the options.

The jsfiddle above will clearly show this problem. Any ideas on how to keep the two in sync?

CodePudding user response:

add this.val = this.options[0]; while running shuffle method, this is because each time the shuffle method runs it resets the options, since your :value is not two way bound, the value is not being updated. Else you can refractor your code and use v-model.

new Vue({
el: "#app",
data: {
    val: 2,
    options: [1, 2, 3, 4]
},

methods: {
    shuffle() {
        this.options = [Math.random(), Math.random(), Math.random()]
        this.val = this.options[0];
    }
}

})

CodePudding user response:

v-model has specific behavior to deal with the situation when a <select>'s options are changed dynamically. Since you're not using v-model, you'll have to deal with these issues yourself.

Like other input elements, a <select> has its own internal state (value and selectedIndex) that the browser maintains (not Vue). If you change the options without changing the value, then when Vue re-renders it won't set the value of the select since the value didn't change, so you're left with whatever state the browser chooses, and potentially the bound value will be out of sync with the actual value of the select.

A couple of solutions:

  • Bind key of the <select> to recreate the element when the options change (fiddle).
  • Wrap the <select> in a component and manually set the selectedIndex of the element to the index of the selected option. Read the v-model source to see how Vue does it.
  • When you change the options data, also change the value data so that it corresponds to an actual option. But this doesn't solve the problem of having the <select> select no option when the value doesn't match any option after changing the options but not the value.
  • Related