Skip to content

Commit

Permalink
fix(model): correctly set select v-model initial value on patch (#6910)
Browse files Browse the repository at this point in the history
  • Loading branch information
gebilaoxiong authored and yyx990803 committed Nov 3, 2017
1 parent 0c703e3 commit 58a39df
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
23 changes: 20 additions & 3 deletions src/platforms/web/runtime/directives/model.js
Expand Up @@ -6,6 +6,8 @@
import { isTextInputType } from 'web/util/element'
import { looseEqual, looseIndexOf } from 'shared/util'
import { warn, isAndroid, isIE9, isIE, isEdge } from 'core/util/index'
import { mergeVNodeHook } from 'core/vdom/helpers/index'
import { emptyNode } from 'core/vdom/patch'

/* istanbul ignore if */
if (isIE9) {
Expand All @@ -18,10 +20,17 @@ if (isIE9) {
})
}

export default {
inserted (el, binding, vnode) {
const directive = {
inserted (el, binding, vnode, oldVnode) {
if (vnode.tag === 'select') {
setSelected(el, binding, vnode.context)
// #6903
if (oldVnode !== emptyNode && !hasDirective(oldVnode, 'model')) {
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'postpatch', () => {
directive.componentUpdated(el, binding, vnode)
})
} else {
setSelected(el, binding, vnode.context)
}
el._vOptions = [].map.call(el.options, getValue)
} else if (vnode.tag === 'textarea' || isTextInputType(el.type)) {
el._vModifiers = binding.modifiers
Expand Down Expand Up @@ -136,3 +145,11 @@ function trigger (el, type) {
e.initEvent(type, true, true)
el.dispatchEvent(e)
}

function hasDirective (vnode, dirname) {
return vnode.data &&
vnode.data.directives &&
vnode.data.directives.some(dir => dir.name === dirname)
}

export default directive
42 changes: 42 additions & 0 deletions test/unit/features/directives/model-select.spec.js
Expand Up @@ -546,4 +546,46 @@ describe('Directive v-model select', () => {
expect(spy).not.toHaveBeenCalled()
}).then(done)
})

// #6903
describe('should correctly handle v-model when the vnodes are the same', () => {
function makeInstance (foo) {
return new Vue({
data: {
foo: foo,
options: ['b', 'c', 'd'],
value: 'c'
},
template:
'<div>' +
'<select v-if="foo" data-attr>' +
'<option selected>a</option>' +
'</select>' +
'<select v-else v-model="value">' +
'<option v-for="option in options" :value="option">{{ option }}</option>' +
'</select>' +
'</div>'
}).$mount()
}

it('register v-model', done => {
const vm = makeInstance(true)

expect(vm.$el.firstChild.selectedIndex).toBe(0)
vm.foo = false
waitForUpdate(() => {
expect(vm.$el.firstChild.selectedIndex).toBe(1)
}).then(done)
})

it('remove v-model', done => {
const vm = makeInstance(false)

expect(vm.$el.firstChild.selectedIndex).toBe(1)
vm.foo = true
waitForUpdate(() => {
expect(vm.$el.firstChild.selectedIndex).toBe(0)
}).then(done)
})
})
})

0 comments on commit 58a39df

Please sign in to comment.