Skip to content

Commit

Permalink
feat: warn if both v-model and v-bind:value used on same element (vue…
Browse files Browse the repository at this point in the history
…js#7056)

* test($compile): warn if v-model and :value used on same text input

vuejs#7048

* test($compile): make v-model and v-bind:value warning apply to all but exceptions

vuejs#7048

* test($compile): move v-model/:value conflict warner to model.js

vuejs#7048

* style: split long warning messages onto new lines
  • Loading branch information
Robert Pemberton authored and hefeng committed Jan 25, 2019
1 parent 1860b41 commit f2bf354
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/platforms/web/compiler/directives/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default function model (
const modifiers = dir.modifiers
const tag = el.tag
const type = el.attrsMap.type
const attrsMap = el.attrsMap

if (process.env.NODE_ENV !== 'production') {
// inputs with type="file" are read only and setting the input's
Expand All @@ -31,6 +32,20 @@ export default function model (
`File inputs are read only. Use a v-on:change listener instead.`
)
}

// warn if v-bind:value conflicts with v-model
if (
(attrsMap['v-bind:value'] || attrsMap[':value']) &&
type !== 'checkbox' &&
type !== 'radio' &&
tag !== 'select'
) {
const vBindValue = attrsMap['v-bind:value'] ? 'v-bind:value' : ':value'
warn(
`${vBindValue} conflicts with v-model on the same element ` +
'because the latter already expands to a value binding internally'
)
}
}

if (el.component) {
Expand Down
26 changes: 26 additions & 0 deletions test/unit/features/directives/model-text.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,32 @@ describe('Directive v-model text', () => {
expect('You are binding v-model directly to a v-for iteration alias').toHaveBeenWarned()
})

it('warn if v-model and v-bind:value conflict', () => {
new Vue({
data: {
test: 'foo'
},
template: '<input type="text" v-model="test" v-bind:value="test"/>'
}).$mount()
expect(
'v-bind:value conflicts with v-model on the same element because the latter already ' +
'expands to a value binding internally'
).toHaveBeenWarned()
})

it('warn if v-model and :value conflict', () => {
new Vue({
data: {
test: 'foo'
},
template: '<input type="text" v-model="test" :value="test"/>'
}).$mount()
expect(
':value conflicts with v-model on the same element because the latter already ' +
'expands to a value binding internally'
).toHaveBeenWarned()
})

if (!isAndroid) {
it('does not trigger extra input events with single compositionend', () => {
const spy = jasmine.createSpy()
Expand Down

0 comments on commit f2bf354

Please sign in to comment.