Skip to content

Commit

Permalink
feat(v-model): warn when v-model is bound on non-existant key
Browse files Browse the repository at this point in the history
Warn when v-model is bound to a non-existant key since that key
will not be reactive.

Fixes vuejs#5932
  • Loading branch information
chriscasola committed Oct 4, 2017
1 parent 94512f3 commit eb848a6
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/compiler/codegen/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,16 @@ function genDirectives (el: ASTElement, state: CodegenState): string | void {
needRuntime = !!gen(el, dir, state.warn)
}
if (needRuntime) {
let warning
hasRuntime = true
res += `{name:"${dir.name}",rawName:"${dir.rawName}"${
dir.value ? `,value:(${dir.value}),expression:${JSON.stringify(dir.value)}` : ''
}${
dir.arg ? `,arg:"${dir.arg}"` : ''
}${
dir.modifiers ? `,modifiers:${JSON.stringify(dir.modifiers)}` : ''
}${
process.env.NODE_ENV !== 'production' && (warning = genValidateValue(dir.value)) ? `,warn:${warning}` : ''
}},`
}
}
Expand Down Expand Up @@ -490,3 +493,15 @@ function transformSpecialNewlines (text: string): string {
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029')
}

function genValidateValue (expr: string): string {
const parts = expr.split('.')
if (parts.length > 1) {
const parent = parts.slice(0, -1).join('.')
const last = parts[parts.length - 1]
if (last.indexOf('[') < 0) {
return `!('${last}' in ${parent}) ? 'You are binding v-model to a key that does not exist, expression: ${expr}' : ''`
}
}
return ''
}
4 changes: 4 additions & 0 deletions src/platforms/web/runtime/directives/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export default {
}
}
}

if (process.env.NODE_ENV !== 'production' && 'warn' in binding) {
warn(binding.warn)
}
},
componentUpdated (el, binding, vnode) {
if (vnode.tag === 'select') {
Expand Down
14 changes: 14 additions & 0 deletions test/unit/features/directives/model-text.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,5 +354,19 @@ describe('Directive v-model text', () => {
done()
}, 16)
})

it('warn binding v-model to non-existant data property', () => {
new Vue({
data: {
testData: {}
},
template: `
<div>
<input v-model="testData.missingKey">
</div>
`
}).$mount()
expect('You are binding v-model to a key that does not exist, expression: testData.missingKey').toHaveBeenWarned()
})
}
})

0 comments on commit eb848a6

Please sign in to comment.