} = instance
const rawCurrentProps = toRaw(props)
const [options] = instance.propsOptions
+ let hasAttrsChanged = false
if (
// always force full diff in dev
// attr / props separation was done on init and will be consistent
// in this code path, so just check if attrs have it.
if (hasOwn(attrs, key)) {
- attrs[key] = value
+ if (value !== attrs[key]) {
+ attrs[key] = value
+ hasAttrsChanged = true
+ }
} else {
const camelizedKey = camelize(key)
props[camelizedKey] = resolvePropValue(
) {
continue
}
- attrs[key] = value
+ if (value !== attrs[key]) {
+ attrs[key] = value
+ hasAttrsChanged = true
+ }
}
}
}
} else {
// full props update.
- setFullProps(instance, rawProps, props, attrs)
+ if (setFullProps(instance, rawProps, props, attrs)) {
+ hasAttrsChanged = true
+ }
// in case of dynamic props, check if we need to delete keys from
// the props object
let kebabKey: string
for (const key in attrs) {
if (!rawProps || !hasOwn(rawProps, key)) {
delete attrs[key]
+ hasAttrsChanged = true
}
}
}
}
// trigger updates for $attrs in case it's used in component slots
- trigger(instance, TriggerOpTypes.SET, '$attrs')
+ if (hasAttrsChanged) {
+ trigger(instance, TriggerOpTypes.SET, '$attrs')
+ }
if (__DEV__) {
validateProps(rawProps || {}, props, instance)
attrs: Data
) {
const [options, needCastKeys] = instance.propsOptions
+ let hasAttrsChanged = false
if (rawProps) {
for (const key in rawProps) {
// key, ref are reserved and never passed down
) {
continue
}
- attrs[key] = value
+ if (value !== attrs[key]) {
+ attrs[key] = value
+ hasAttrsChanged = true
+ }
}
}
}
)
}
}
+
+ return hasAttrsChanged
}
function resolvePropValue(