diff --git a/src/core/vdom/create-component.js b/src/core/vdom/create-component.js index a9799cda085..d1730c50919 100644 --- a/src/core/vdom/create-component.js +++ b/src/core/vdom/create-component.js @@ -287,6 +287,18 @@ function extractProps (data: VNodeData, Ctor: Class): ?Object { if (attrs || props || domProps) { for (const key in propOptions) { const altKey = hyphenate(key) + if (process.env.NODE_ENV !== 'production') { + const keyInLowerCase = key.toLowerCase() + if ( + key !== keyInLowerCase && + attrs && attrs.hasOwnProperty(keyInLowerCase) + ) { + warn( + `HTML attributes are case-insensitive. camelCased prop names need ` + + `to use their kebab-case equivalents. ${key} should be ${altKey}.` + ) + } + } checkProp(res, props, key, altKey, true) || checkProp(res, attrs, key, altKey) || checkProp(res, domProps, key, altKey) diff --git a/test/unit/features/component/component.spec.js b/test/unit/features/component/component.spec.js index 2e57332e52e..b479434804a 100644 --- a/test/unit/features/component/component.spec.js +++ b/test/unit/features/component/component.spec.js @@ -258,6 +258,25 @@ describe('Component', () => { expect(vm.$el.outerHTML).toBe('') }) + it('should warn when not passing props in kebab-case', () => { + new Vue({ + data: { + list: [{ a: 1 }, { a: 2 }] + }, + template: '', + components: { + test: { + template: '', + props: ['someCollection'] + } + } + }).$mount() + expect( + 'HTML attributes are case-insensitive. camelCased prop names need ' + + 'to use their kebab-case equivalents. someCollection should be some-collection.' + ).toHaveBeenWarned() + }) + it('not found component should not throw', () => { expect(function () { new Vue({