refactor: group all extracted non-props under $props.attrs, including class and

style.
This commit is contained in:
Evan You 2018-09-24 00:29:37 -04:00
parent b5db956f9a
commit f398c129e6
2 changed files with 20 additions and 36 deletions

View File

@ -50,22 +50,28 @@ export function normalizeComponentProps(
const res: Data = {} const res: Data = {}
if (raw) { if (raw) {
for (const key in raw) { for (const key in raw) {
if (key === 'key' || key === 'ref' || key === 'slot') { // key, ref, slots are reserved
if (key === 'key' || key === 'ref' || key === 'slots') {
continue continue
} }
if (hasDeclaredProps) { // class, style & nativeOn are always extracted into a separate `attrs`
if (options.hasOwnProperty(key)) { // object, which can then be merged onto child component root.
if (__DEV__) { // in addition, if the component has explicitly declared props, then
// any non-matching props are extracted into `attrs` as well.
let isNativeOn
if (
key === 'class' ||
key === 'style' ||
(isNativeOn = key.startsWith('nativeOn')) ||
(hasDeclaredProps && !options.hasOwnProperty(key))
) {
const newKey = isNativeOn ? 'on' + key.slice(8) : key
;(res.attrs || (res.attrs = {}))[newKey] = raw[key]
} else {
if (__DEV__ && hasDeclaredProps && options.hasOwnProperty(key)) {
validateProp(key, raw[key], options[key], Component) validateProp(key, raw[key], options[key], Component)
} }
res[key] = raw[key] res[key] = raw[key]
} else {
// when props are explicitly declared, any non-matching prop is
// extracted into attrs instead.
;(res.attrs || (res.attrs = {}))[key] = raw[key]
}
} else {
res[key] = raw[key]
} }
} }
} }

View File

@ -109,30 +109,8 @@ export function normalizeComponentRoot(
(flags & VNodeFlags.COMPONENT || flags & VNodeFlags.ELEMENT) (flags & VNodeFlags.COMPONENT || flags & VNodeFlags.ELEMENT)
) { ) {
const parentData = componentVNode.data const parentData = componentVNode.data
if (parentData != null && inheritAttrs !== false) { if (inheritAttrs !== false && parentData && parentData.attrs) {
let extraData: any = null vnode = cloneVNode(vnode, parentData.attrs)
for (const key in parentData) {
// attrs/class/style bindings on parentVNode are merged down to child
// component root,
// nativeOn* handlers are merged to child root as normal on* handlers.
// cloneVNode contains special logic for merging these props with
// existing values.
if (key === 'attrs') {
extraData = extraData || {}
const { attrs } = parentData
for (const attr in attrs) {
extraData[attr] = attrs[attr]
}
} else if (key === 'class' || key === 'style') {
;(extraData || (extraData = {}))[key] = parentData[key]
} else if (key.startsWith('nativeOn')) {
;(extraData || (extraData = {}))['on' + key.slice(8)] =
parentData[key]
}
}
if (extraData) {
vnode = cloneVNode(vnode, extraData)
}
} }
if (vnode.el) { if (vnode.el) {
vnode = cloneVNode(vnode) vnode = cloneVNode(vnode)