wip: class/style fallthrough compat
This commit is contained in:
parent
a75b00c558
commit
12abd4af85
22
packages/runtime-core/src/compat/attrsFallthrough.ts
Normal file
22
packages/runtime-core/src/compat/attrsFallthrough.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { isOn } from '@vue/shared'
|
||||
import { ComponentInternalInstance } from '../component'
|
||||
import { DeprecationTypes, isCompatEnabled } from './compatConfig'
|
||||
|
||||
export function shouldSkipAttr(
|
||||
key: string,
|
||||
instance: ComponentInternalInstance
|
||||
): boolean {
|
||||
if (
|
||||
(key === 'class' || key === 'style') &&
|
||||
isCompatEnabled(DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE, instance)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
if (
|
||||
isOn(key) &&
|
||||
isCompatEnabled(DeprecationTypes.INSTANCE_LISTENERS, instance)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
@ -216,15 +216,15 @@ const deprecationData: Record<DeprecationTypes, DeprecationData> = {
|
||||
},
|
||||
|
||||
[DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE]: {
|
||||
message:
|
||||
`vm.$attrs now includes class and style bindings passed from parent. ` +
|
||||
`Components with inheritAttrs: false will no longer auto-inherit ` +
|
||||
`class/style on its root element. If your code relies on this behavior, ` +
|
||||
`you may see broken styling and need to adjust your CSS. Otherwise, ` +
|
||||
`you can disable the compat behavior and suppress this warning with:` +
|
||||
`\n\n configureCompat({ ${
|
||||
DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE
|
||||
}: false )\n`,
|
||||
message: componentName =>
|
||||
`Component <${componentName}> has \`inheritAttrs: false\` but is ` +
|
||||
`relying on class/style fallthrough from parent. In Vue 3, class/style ` +
|
||||
`are now included in $attrs and will no longer fallthrough when ` +
|
||||
`inheritAttrs is false. If you are already using v-bind="$attrs" on ` +
|
||||
`component root it should render the same end result. ` +
|
||||
`If you are binding $attrs to a non-root element and expecting ` +
|
||||
`class/style to fallthrough on root, you will need to now manually bind ` +
|
||||
`them on root via :class="$attrs.class".`,
|
||||
link: `https://v3.vuejs.org/guide/migration/attrs-includes-class-style.html`
|
||||
},
|
||||
|
||||
|
@ -4,7 +4,6 @@ import { getCompatChildren } from './instanceChildren'
|
||||
import {
|
||||
DeprecationTypes,
|
||||
assertCompatEnabled,
|
||||
checkCompatEnabled,
|
||||
isCompatEnabled
|
||||
} from './compatConfig'
|
||||
import { off, on, once } from './instanceEventEmitter'
|
||||
@ -75,14 +74,6 @@ export function installCompatInstanceProperties(map: PublicPropertiesMap) {
|
||||
return __DEV__ ? shallowReadonly(i.slots) : i.slots
|
||||
},
|
||||
|
||||
// overrides existing accessor
|
||||
$attrs: i => {
|
||||
if (__DEV__ && i.type.inheritAttrs === false) {
|
||||
checkCompatEnabled(DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE, i)
|
||||
}
|
||||
return __DEV__ ? shallowReadonly(i.attrs) : i.attrs
|
||||
},
|
||||
|
||||
$on: i => on.bind(null, i),
|
||||
$once: i => once.bind(null, i),
|
||||
$off: i => off.bind(null, i),
|
||||
|
@ -20,8 +20,7 @@ import {
|
||||
isReservedProp,
|
||||
EMPTY_ARR,
|
||||
def,
|
||||
extend,
|
||||
isOn
|
||||
extend
|
||||
} from '@vue/shared'
|
||||
import { warn } from './warning'
|
||||
import {
|
||||
@ -37,6 +36,7 @@ import { AppContext } from './apiCreateApp'
|
||||
import { createPropsDefaultThis } from './compat/props'
|
||||
import { isCompatEnabled, softAssertCompatEnabled } from './compat/compatConfig'
|
||||
import { DeprecationTypes } from './compat/compatConfig'
|
||||
import { shouldSkipAttr } from './compat/attrsFallthrough'
|
||||
|
||||
export type ComponentPropsOptions<P = Data> =
|
||||
| ComponentObjectPropsOptions<P>
|
||||
@ -229,11 +229,7 @@ export function updateProps(
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
__COMPAT__ &&
|
||||
isOn(key) &&
|
||||
isCompatEnabled(DeprecationTypes.INSTANCE_LISTENERS, instance)
|
||||
) {
|
||||
if (__COMPAT__ && shouldSkipAttr(key, instance)) {
|
||||
continue
|
||||
}
|
||||
if (value !== attrs[key]) {
|
||||
@ -341,11 +337,7 @@ function setFullProps(
|
||||
// Any non-declared (either as a prop or an emitted event) props are put
|
||||
// into a separate `attrs` object for spreading. Make sure to preserve
|
||||
// original key casing
|
||||
if (
|
||||
__COMPAT__ &&
|
||||
isOn(key) &&
|
||||
isCompatEnabled(DeprecationTypes.INSTANCE_LISTENERS, instance)
|
||||
) {
|
||||
if (__COMPAT__ && shouldSkipAttr(key, instance)) {
|
||||
continue
|
||||
}
|
||||
if (value !== attrs[key]) {
|
||||
|
@ -1,7 +1,8 @@
|
||||
import {
|
||||
ComponentInternalInstance,
|
||||
FunctionalComponent,
|
||||
Data
|
||||
Data,
|
||||
getComponentName
|
||||
} from './component'
|
||||
import {
|
||||
VNode,
|
||||
@ -20,6 +21,11 @@ import { isHmrUpdating } from './hmr'
|
||||
import { NormalizedProps } from './componentProps'
|
||||
import { isEmitListener } from './componentEmits'
|
||||
import { setCurrentRenderingInstance } from './componentRenderContext'
|
||||
import {
|
||||
DeprecationTypes,
|
||||
isCompatEnabled,
|
||||
warnDeprecation
|
||||
} from './compat/compatConfig'
|
||||
|
||||
/**
|
||||
* dev only flag to track whether $attrs was used during render.
|
||||
@ -117,7 +123,7 @@ export function renderComponentRoot(
|
||||
;[root, setRoot] = getChildRoot(result)
|
||||
}
|
||||
|
||||
if (Component.inheritAttrs !== false && fallthroughAttrs) {
|
||||
if (fallthroughAttrs && Component.inheritAttrs !== false) {
|
||||
const keys = Object.keys(fallthroughAttrs)
|
||||
const { shapeFlag } = root
|
||||
if (keys.length) {
|
||||
@ -175,6 +181,29 @@ export function renderComponentRoot(
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
__COMPAT__ &&
|
||||
isCompatEnabled(DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE, instance) &&
|
||||
vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT &&
|
||||
(root.shapeFlag & ShapeFlags.ELEMENT ||
|
||||
root.shapeFlag & ShapeFlags.COMPONENT)
|
||||
) {
|
||||
const { class: cls, style } = vnode.props || {}
|
||||
if (cls || style) {
|
||||
if (__DEV__ && Component.inheritAttrs === false) {
|
||||
warnDeprecation(
|
||||
DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE,
|
||||
instance,
|
||||
getComponentName(instance.type)
|
||||
)
|
||||
}
|
||||
root = cloneVNode(root, {
|
||||
class: cls,
|
||||
style: style
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// inherit directives
|
||||
if (vnode.dirs) {
|
||||
if (__DEV__ && !isElementRoot(root)) {
|
||||
|
Loading…
Reference in New Issue
Block a user