Consider the following code:
<div id="demo">
<select v-model="selected" number>
<option v-for="opt in options" :value="$index" number>{{opt}}</option>
</select>
</div>
In <select>
, each option value is bound with $index
. If we perform splice()
on options
, like, options.splice(0,1)
, $index
does not correctly sync with options.
For example, let options=['a','b']
and the rendered HTML looks like (but not really):
<div id="demo">
<select selectedIndex="0">
<option value="0">a</option>
<option value="1">b</option>
</select>
</div>
After options.splice(0,1)
, then options=['b']
, but the rendered HTML becomes:
<div id="demo">
<select selectedIndex="0">
<option value="1">b</option>
</select>
</div>
The value of 'b' option does not become 1, which should be 0 because of $index
. This may not be a bug, but this is kind of odd.
Below is the live demo of this issue:
https://jsfiddle.net/peteranny/trwp98g9/4/
Just add a selected attribute in your template selected="{{$index == selected}}"
I update the demo here https://jsfiddle.net/trwp98g9/5/
@peteranny Can you clarify what was the expected behavior?
After options.splice(0,1), then options=['b'], but the rendered HTML becomes:
<option value="1">b</option>
I'm not getting the same result as you provided from here:
Before clicking remove:
After clicking:
The value of 'b' option does not become 1, which should be 0 because of $index
So what exactly should it become? The value of 'b' was 1 before click, and became 0 after click.
@fnlctrl Um, thank you for your testing. I think I've asked the wrong question.
According to your testing, the value of 'b' did become 0 after click.
My true question is: now that the value of 'b' was 0, why was <select>
not selecting 'b' anyway?
As seen in your image, <select>
did not select any option at all, while <select>
is ought to select the option with the value 0.
(And that is why I misguessed that the value of 'b' didn't change.)
@peteranny It may be a bug because selected
remained 0 while the options
changed, and the dom is supposed to reflect this change, but I'm not sure..
For now, you can try adding selected
prop as @defcc suggested, (note that mustache binding for props/attrs is deprecated in 2.0, so please use :selected="$index == selected"
instead)
Or you can add a track-by
prop to <options>
, which probably made vue think it's safe to update the selected value in dom. https://jsfiddle.net/74ncq90w/
Tested on 2.0 and it worked as expected: https://jsfiddle.net/dycmgzcm/
So I'm marking this as a bug of 1.x
Closing 1.x issues as 1.x is now end of life and will only receive critical security patches.
Most helpful comment
Tested on 2.0 and it worked as expected: https://jsfiddle.net/dycmgzcm/
So I'm marking this as a bug of 1.x