Skip to content

Commit

Permalink
update dom prop for option.value (fix #4494) (#4505)
Browse files Browse the repository at this point in the history
* update dom prop for option.value

* refactor value update logic
  • Loading branch information
defcc authored and yyx990803 committed Dec 21, 2016
1 parent a977642 commit be9210f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
23 changes: 18 additions & 5 deletions src/platforms/web/runtime/modules/dom-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

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

// check platforms/web/util/attrs.js acceptValue
declare type acceptValueElm = HTMLInputElement | HTMLSelectElement | HTMLOptionElement

function updateDOMProps (oldVnode: VNodeWithData, vnode: VNodeWithData) {
if (!oldVnode.data.domProps && !vnode.data.domProps) {
return
Expand Down Expand Up @@ -35,10 +38,7 @@ function updateDOMProps (oldVnode: VNodeWithData, vnode: VNodeWithData) {
elm._value = cur
// avoid resetting cursor position when value is the same
const strCur = cur == null ? '' : String(cur)
if (!elm.composing && (
(document.activeElement !== elm && elm.value !== strCur) ||
isValueChanged(vnode, strCur)
)) {
if (needUpdateValue(elm, vnode, strCur)) {
elm.value = strCur
}
} else {
Expand All @@ -47,7 +47,20 @@ function updateDOMProps (oldVnode: VNodeWithData, vnode: VNodeWithData) {
}
}

function isValueChanged (vnode: VNodeWithData, newVal: string): boolean {
function needUpdateValue (elm: acceptValueElm, vnode: VNodeWithData, checkVal: string): boolean {
// inputing
if (elm.composing) return false
if (elm.tagName.toLowerCase() === 'option') return true
if (isDirty(elm, checkVal)) return true
if (isInputChanged(vnode, checkVal)) return true
return false
}

function isDirty (elm: acceptValueElm, checkVal: string): boolean {
return document.activeElement !== elm && elm.value !== checkVal
}

function isInputChanged (vnode: VNodeWithData, newVal: string): boolean {
const value = vnode.elm.value
const modifiers = vnode.elm._vModifiers // injected by v-model runtime
if ((modifiers && modifiers.number) || vnode.elm.type === 'number') {
Expand Down
11 changes: 11 additions & 0 deletions test/unit/features/directives/bind.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,17 @@ describe('Directive v-bind', () => {
expect('v-bind without argument expects an Object or Array value').toHaveBeenWarned()
})

it('set value for option element', () => {
const vm = new Vue({
template: '<select><option :value="val">val</option></select>',
data: {
val: 'val'
}
}).$mount()
// check value attribute
expect(vm.$el.options[0].getAttribute('value')).toBe('val')
})

// a vdom patch edge case where the user has several un-keyed elements of the
// same tag next to each other, and toggling them.
it('properly update for toggling un-keyed children', done => {
Expand Down

0 comments on commit be9210f

Please sign in to comment.