From d33c1250ee77dd337eb4979851ade331f177b890 Mon Sep 17 00:00:00 2001 From: gebilaoxiong Date: Fri, 16 Jun 2017 20:40:56 +0800 Subject: [PATCH] fix:when using object syntax in v-bind, special attribute have no effect --- flow/vnode.js | 1 + .../instance/render-helpers/bind-object-props.js | 14 ++++++++++++-- src/core/instance/state.js | 11 +++-------- src/core/vdom/create-element.js | 4 ++++ src/shared/util.js | 5 +++++ 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/flow/vnode.js b/flow/vnode.js index fba62ee3..8a3622b4 100644 --- a/flow/vnode.js +++ b/flow/vnode.js @@ -35,6 +35,7 @@ declare interface VNodeData { key?: string | number; slot?: string; ref?: string; + is?: string; pre?: boolean; tag?: string; staticClass?: string; diff --git a/src/core/instance/render-helpers/bind-object-props.js b/src/core/instance/render-helpers/bind-object-props.js index dc42b53f..cc50c2d9 100644 --- a/src/core/instance/render-helpers/bind-object-props.js +++ b/src/core/instance/render-helpers/bind-object-props.js @@ -1,7 +1,13 @@ /* @flow */ import config from 'core/config' -import { isObject, warn, toObject } from 'core/util/index' + +import { + warn, + isObject, + toObject, + isReservedAttribute +} from 'core/util/index' /** * Runtime helper for merging v-bind="object" into a VNode's data. @@ -24,7 +30,11 @@ export function bindObjectProps ( } let hash for (const key in value) { - if (key === 'class' || key === 'style') { + if ( + key === 'class' || + key === 'style' || + isReservedAttribute(key) + ) { hash = data } else { const type = data.attrs && data.attrs.type diff --git a/src/core/instance/state.js b/src/core/instance/state.js index c099aaec..f71c0b8e 100644 --- a/src/core/instance/state.js +++ b/src/core/instance/state.js @@ -20,7 +20,8 @@ import { isReserved, handleError, validateProp, - isPlainObject + isPlainObject, + isReservedAttribute } from '../util/index' const sharedPropertyDefinition = { @@ -54,12 +55,6 @@ export function initState (vm: Component) { if (opts.watch) initWatch(vm, opts.watch) } -const isReservedProp = { - key: 1, - ref: 1, - slot: 1 -} - function checkOptionType (vm: Component, name: string) { const option = vm.$options[name] if (!isPlainObject(option)) { @@ -84,7 +79,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] || config.isReservedAttr(key)) { + if (isReservedAttribute(key) || config.isReservedAttr(key)) { warn( `"${key}" is a reserved attribute and cannot be used as component prop.`, vm diff --git a/src/core/vdom/create-element.js b/src/core/vdom/create-element.js index a7b650d5..783cfa71 100644 --- a/src/core/vdom/create-element.js +++ b/src/core/vdom/create-element.js @@ -57,6 +57,10 @@ export function _createElement ( ) return createEmptyVNode() } + // object syntax in v-bind + if (isDef(data) && isDef(data.is)) { + tag = data.is + } if (!tag) { // in case of component :is set to falsy value return createEmptyVNode() diff --git a/src/shared/util.js b/src/shared/util.js index 922bcd2b..8fbb1b81 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -90,6 +90,11 @@ export function makeMap ( */ export const isBuiltInTag = makeMap('slot,component', true) +/** + * Check if a attribute is a reserved attribute. + */ +export const isReservedAttribute = makeMap('key,ref,slot,is') + /** * Remove an item from an array */