Skip to content

Commit be9210f

Browse files
defccyyx990803
authored andcommitted
update dom prop for option.value (fix #4494) (#4505)
* update dom prop for option.value * refactor value update logic
1 parent a977642 commit be9210f

File tree

2 files changed

+29
-5
lines changed

2 files changed

+29
-5
lines changed

src/platforms/web/runtime/modules/dom-props.js

+18-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import { extend, toNumber } from 'shared/util'
44

5+
// check platforms/web/util/attrs.js acceptValue
6+
declare type acceptValueElm = HTMLInputElement | HTMLSelectElement | HTMLOptionElement
7+
58
function updateDOMProps (oldVnode: VNodeWithData, vnode: VNodeWithData) {
69
if (!oldVnode.data.domProps && !vnode.data.domProps) {
710
return
@@ -35,10 +38,7 @@ function updateDOMProps (oldVnode: VNodeWithData, vnode: VNodeWithData) {
3538
elm._value = cur
3639
// avoid resetting cursor position when value is the same
3740
const strCur = cur == null ? '' : String(cur)
38-
if (!elm.composing && (
39-
(document.activeElement !== elm && elm.value !== strCur) ||
40-
isValueChanged(vnode, strCur)
41-
)) {
41+
if (needUpdateValue(elm, vnode, strCur)) {
4242
elm.value = strCur
4343
}
4444
} else {
@@ -47,7 +47,20 @@ function updateDOMProps (oldVnode: VNodeWithData, vnode: VNodeWithData) {
4747
}
4848
}
4949

50-
function isValueChanged (vnode: VNodeWithData, newVal: string): boolean {
50+
function needUpdateValue (elm: acceptValueElm, vnode: VNodeWithData, checkVal: string): boolean {
51+
// inputing
52+
if (elm.composing) return false
53+
if (elm.tagName.toLowerCase() === 'option') return true
54+
if (isDirty(elm, checkVal)) return true
55+
if (isInputChanged(vnode, checkVal)) return true
56+
return false
57+
}
58+
59+
function isDirty (elm: acceptValueElm, checkVal: string): boolean {
60+
return document.activeElement !== elm && elm.value !== checkVal
61+
}
62+
63+
function isInputChanged (vnode: VNodeWithData, newVal: string): boolean {
5164
const value = vnode.elm.value
5265
const modifiers = vnode.elm._vModifiers // injected by v-model runtime
5366
if ((modifiers && modifiers.number) || vnode.elm.type === 'number') {

test/unit/features/directives/bind.spec.js

+11
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,17 @@ describe('Directive v-bind', () => {
248248
expect('v-bind without argument expects an Object or Array value').toHaveBeenWarned()
249249
})
250250

251+
it('set value for option element', () => {
252+
const vm = new Vue({
253+
template: '<select><option :value="val">val</option></select>',
254+
data: {
255+
val: 'val'
256+
}
257+
}).$mount()
258+
// check value attribute
259+
expect(vm.$el.options[0].getAttribute('value')).toBe('val')
260+
})
261+
251262
// a vdom patch edge case where the user has several un-keyed elements of the
252263
// same tag next to each other, and toggling them.
253264
it('properly update for toggling un-keyed children', done => {

0 commit comments

Comments
 (0)