Skip to content

Commit 1f89cc9

Browse files
committed
allow v-bind="$attrs" with v-on="$listeners" to work with v-model
1 parent c628103 commit 1f89cc9

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

src/compiler/directives/model.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export function genAssignmentCode (
3939
): string {
4040
const modelRs = parseModel(value)
4141
if (modelRs.idx === null) {
42-
return `${value}=${assignment}`
42+
return `if (typeof (${assignment}) === 'object' && (${assignment}).type === 'input') { ${value}=(${assignment}).target.value } else { ${value}=${assignment} }`
4343
} else {
4444
return `$set(${modelRs.exp}, ${modelRs.idx}, ${assignment})`
4545
}

src/core/vdom/create-component.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ function mergeHook (one: Function, two: Function): Function {
245245
function transformModel (options, data: any) {
246246
const prop = (options.model && options.model.prop) || 'value'
247247
const event = (options.model && options.model.event) || 'input'
248-
;(data.props || (data.props = {}))[prop] = data.model.value
248+
;(data.attrs || (data.attrs = {}))[prop] = data.model.value
249249
const on = data.on || (data.on = {})
250250
if (isDef(on[event])) {
251251
on[event] = [data.model.callback].concat(on[event])

test/unit/features/directives/model-component.spec.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,38 @@ describe('Directive v-model component', () => {
148148
vm.$refs.input.$emit('input', ' foo o ')
149149
expect(vm.text).toBe('foo o')
150150
})
151+
152+
it('should work with v-bind="$attrs" plus v-on="$listeners"', done => {
153+
const vm = new Vue({
154+
data: {
155+
msg: 'hello'
156+
},
157+
template: `
158+
<div>
159+
<p>{{ msg }}</p>
160+
<test v-model="msg"></test>
161+
</div>
162+
`,
163+
components: {
164+
test: {
165+
template: `<input v-bind="$attrs" v-on="$listeners">`
166+
}
167+
}
168+
}).$mount()
169+
document.body.appendChild(vm.$el)
170+
waitForUpdate(() => {
171+
const input = vm.$el.querySelector('input')
172+
input.value = 'world'
173+
triggerEvent(input, 'input')
174+
}).then(() => {
175+
expect(vm.msg).toEqual('world')
176+
expect(vm.$el.querySelector('p').textContent).toEqual('world')
177+
vm.msg = 'changed'
178+
}).then(() => {
179+
expect(vm.$el.querySelector('p').textContent).toEqual('changed')
180+
expect(vm.$el.querySelector('input').value).toEqual('changed')
181+
}).then(() => {
182+
document.body.removeChild(vm.$el)
183+
}).then(done)
184+
})
151185
})

0 commit comments

Comments
 (0)