diff --git a/src/compiler/error-detector.js b/src/compiler/error-detector.js index 3d1403a9448..9893aa4a47a 100644 --- a/src/compiler/error-detector.js +++ b/src/compiler/error-detector.js @@ -31,12 +31,13 @@ function checkNode (node: ASTNode, warn: Function) { if (node.type === 1) { for (const name in node.attrsMap) { if (dirRE.test(name)) { - if (name === 'v-slot') break; const value = node.attrsMap[name] if (value) { const range = node.rawAttrsMap[name] if (name === 'v-for') { checkFor(node, `v-for="${value}"`, warn, range) + } else if (name === 'v-slot' || name[0] === '#') { + checkFunctionParameterExpression(value, `${name}="${value}"`, warn, range) } else if (onRE.test(name)) { checkEvent(value, `${name}="${value}"`, warn, range) } else { @@ -112,3 +113,16 @@ function checkExpression (exp: string, text: string, warn: Function, range?: Ran } } } + +function checkFunctionParameterExpression (exp: string, text: string, warn: Function, range?: Range) { + try { + new Function(exp, '') + } catch (e) { + warn( + `invalid function parameter expression: ${e.message} in\n\n` + + ` ${exp}\n\n` + + ` Raw expression: ${text.trim()}\n`, + range + ) + } +} diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js index fb258752179..cdeb257eda4 100644 --- a/src/compiler/parser/index.js +++ b/src/compiler/parser/index.js @@ -23,8 +23,8 @@ import { export const onRE = /^@|^v-on:/ export const dirRE = process.env.VBIND_PROP_SHORTHAND - ? /^v-|^@|^:|^\./ - : /^v-|^@|^:/ + ? /^v-|^@|^:|^\.|^#/ + : /^v-|^@|^:|^#/ export const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/ export const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/ const stripParensRE = /^\(|\)$/g diff --git a/test/unit/features/component/component-scoped-slot.spec.js b/test/unit/features/component/component-scoped-slot.spec.js index d0fcc3e8252..28369814f48 100644 --- a/test/unit/features/component/component-scoped-slot.spec.js +++ b/test/unit/features/component/component-scoped-slot.spec.js @@ -760,12 +760,20 @@ describe('Component scoped slot', () => { expect(`Unexpected mixed usage of different slot syntaxes`).toHaveBeenWarned() }) + it('should warn invalid parameter expression', () => { + new Vue({ + template: ``, + components: { Foo } + }).$mount(); + expect('invalid function parameter expression').toHaveBeenWarned() + }) + it('should allow destructuring props with default value', () => { new Vue({ template: ``, - components: { Foo, Bar } + components: { Foo } }).$mount(); - expect('Invalid shorthand property initializer').not.toHaveBeenWarned() + expect('invalid function parameter expression').not.toHaveBeenWarned() }) }