diff --git a/src/core/config.js b/src/core/config.js index ca3b7736315..474491331e7 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -18,6 +18,7 @@ export type Config = { keyCodes: { [key: string]: number | Array }; // platform isReservedTag: (x?: string) => boolean; + isReservedAttr: (x?: string) => boolean; parsePlatformTagName: (x: string) => string; isUnknownElement: (x?: string) => boolean; getTagNamespace: (x?: string) => string | void; @@ -71,6 +72,12 @@ export default ({ */ isReservedTag: no, + /** + * Check if an attribute is reserved so that it cannot be used as a component + * prop. This is platform-dependent and may be overwritten. + */ + isReservedAttr: no, + /** * Check if a tag is an unknown element. * Platform-dependent. diff --git a/src/core/instance/state.js b/src/core/instance/state.js index a6036018d78..d2d8fa14998 100644 --- a/src/core/instance/state.js +++ b/src/core/instance/state.js @@ -1,5 +1,6 @@ /* @flow */ +import config from '../config' import Dep from '../observer/dep' import Watcher from '../observer/watcher' @@ -53,7 +54,11 @@ export function initState (vm: Component) { if (opts.watch) initWatch(vm, opts.watch) } -const isReservedProp = { key: 1, ref: 1, slot: 1 } +const isReservedProp = { + key: 1, + ref: 1, + slot: 1 +} function initProps (vm: Component, propsOptions: Object) { const propsData = vm.$options.propsData || {} @@ -69,7 +74,7 @@ function initProps (vm: Component, propsOptions: Object) { const value = validateProp(key, propsOptions, propsData, vm) /* istanbul ignore else */ if (process.env.NODE_ENV !== 'production') { - if (isReservedProp[key]) { + if (isReservedProp[key] || config.isReservedAttr(key)) { warn( `"${key}" is a reserved attribute and cannot be used as component prop.`, vm diff --git a/src/entries/web-runtime.js b/src/entries/web-runtime.js index 3d0a76ef658..7e55d6ae8db 100644 --- a/src/entries/web-runtime.js +++ b/src/entries/web-runtime.js @@ -13,6 +13,7 @@ import { query, mustUseProp, isReservedTag, + isReservedAttr, getTagNamespace, isUnknownElement } from 'web/util/index' @@ -20,6 +21,7 @@ import { // install platform specific utils Vue.config.mustUseProp = mustUseProp Vue.config.isReservedTag = isReservedTag +Vue.config.isReservedAttr = isReservedAttr Vue.config.getTagNamespace = getTagNamespace Vue.config.isUnknownElement = isUnknownElement diff --git a/src/platforms/web/util/attrs.js b/src/platforms/web/util/attrs.js index c8afc748a07..1758b4708b5 100644 --- a/src/platforms/web/util/attrs.js +++ b/src/platforms/web/util/attrs.js @@ -2,6 +2,10 @@ import { makeMap } from 'shared/util' +// these are reserved for web because they are directly compiled away +// during template compilation +export const isReservedAttr = makeMap('style,class') + // attributes that should be using props for binding const acceptValue = makeMap('input,textarea,option,select') export const mustUseProp = (tag: string, type: ?string, attr: string): boolean => {