Skip to content

Commit

Permalink
feat: support v-model dynamic type binding for v-bind="object"
Browse files Browse the repository at this point in the history
close #7296
  • Loading branch information
yyx990803 committed Dec 21, 2017
1 parent d8b0838 commit 41838c8
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
15 changes: 13 additions & 2 deletions src/platforms/web/compiler/modules/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,19 @@ import {
function preTransformNode (el: ASTElement, options: CompilerOptions) {
if (el.tag === 'input') {
const map = el.attrsMap
if (map['v-model'] && (map['v-bind:type'] || map[':type'])) {
const typeBinding: any = getBindingAttr(el, 'type')
if (!map['v-model']) {
return
}

let typeBinding
if (map[':type'] || map['v-bind:type']) {
typeBinding = getBindingAttr(el, 'type')
}
if (!typeBinding && map['v-bind']) {
typeBinding = `(${map['v-bind']}).type`
}

if (typeBinding) {
const ifCondition = getAndRemoveAttr(el, 'v-if', true)
const ifConditionExtra = ifCondition ? `&&(${ifCondition})` : ``
const hasElse = getAndRemoveAttr(el, 'v-else', true) != null
Expand Down
50 changes: 50 additions & 0 deletions test/unit/features/directives/model-dynamic.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,56 @@ describe('Directive v-model dynamic input type', () => {
expect(vm.data.text).toBe('foo')
}).then(done)
})

it('with v-bind', done => {
const vm = new Vue({
data: {
data: {
text: 'foo',
checkbox: true
},
inputs: [{ id: 'one', type: 'text' }, { id: 'two', type: 'checkbox' }]
},
template: `<div>
<input v-for="i in inputs" v-bind="i" v-model="data[i.type]">
</div>`
}).$mount()
document.body.appendChild(vm.$el)

let el1 = vm.$el.children[0]
expect(el1.id).toBe('one')
expect(el1.type).toBe('text')
expect(el1.value).toBe('foo')
el1.value = 'bar'
triggerEvent(el1, 'input')
expect(vm.data.text).toBe('bar')

let el2 = vm.$el.children[1]
expect(el2.id).toBe('two')
expect(el2.type).toBe('checkbox')
expect(el2.checked).toBe(true)
el2.click()
expect(vm.data.checkbox).toBe(false)

// now in reverse!
vm.inputs.reverse()
waitForUpdate(() => {
el1 = vm.$el.children[0]
expect(el1.id).toBe('two')
expect(el1.type).toBe('checkbox')
expect(el1.checked).toBe(false)
el1.click()
expect(vm.data.checkbox).toBe(true)

el2 = vm.$el.children[1]
expect(el2.id).toBe('one')
expect(el2.type).toBe('text')
expect(el2.value).toBe('bar')
el2.value = 'foo'
triggerEvent(el2, 'input')
expect(vm.data.text).toBe('foo')
}).then(done)
})
})

function assertInputWorks (vm, type, chain) {
Expand Down

0 comments on commit 41838c8

Please sign in to comment.