wip: warn v-bind object ordering
This commit is contained in:
parent
bf41354abd
commit
2c31227e7c
@ -54,10 +54,10 @@ const deprecationData: Record<CompilerDeprecationTypes, DeprecationData> = {
|
|||||||
[CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER]: {
|
[CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER]: {
|
||||||
message:
|
message:
|
||||||
`v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
|
`v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
|
||||||
`object spread: it will now overwrite an existing attribute that appears ` +
|
`object spread: it will now overwrite an existing non-mergeable attribute ` +
|
||||||
`before v-bind in the case of conflicting keys. To retain 2.x behavior, ` +
|
`that appears before v-bind in the case of conflict. ` +
|
||||||
`move v-bind to and make it the first attribute. If all occurences ` +
|
`To retain 2.x behavior, move v-bind to make it the first attribute. ` +
|
||||||
`of this warning are working as intended, you can suppress it.`,
|
`You can also suppress this warning if the usage is intended.`,
|
||||||
link: `https://v3.vuejs.org/guide/migration/v-bind.html`
|
link: `https://v3.vuejs.org/guide/migration/v-bind.html`
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -98,17 +98,24 @@ function getCompatValue(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isCompatEnabled(
|
||||||
|
key: CompilerDeprecationTypes,
|
||||||
|
context: ParserContext | TransformContext
|
||||||
|
) {
|
||||||
|
const mode = getCompatValue('MODE', context)
|
||||||
|
const value = getCompatValue(key, context)
|
||||||
|
// in v3 mode, only enable if explicitly set to true
|
||||||
|
// otherwise enable for any non-false value
|
||||||
|
return mode === 3 ? value === true : value !== false
|
||||||
|
}
|
||||||
|
|
||||||
export function checkCompatEnabled(
|
export function checkCompatEnabled(
|
||||||
key: CompilerDeprecationTypes,
|
key: CompilerDeprecationTypes,
|
||||||
context: ParserContext | TransformContext,
|
context: ParserContext | TransformContext,
|
||||||
loc: SourceLocation | null,
|
loc: SourceLocation | null,
|
||||||
...args: any[]
|
...args: any[]
|
||||||
): boolean {
|
): boolean {
|
||||||
const mode = getCompatValue('MODE', context)
|
const enabled = isCompatEnabled(key, context)
|
||||||
const value = getCompatValue(key, context)
|
|
||||||
// in v3 mode, only enable if explicitly set to true
|
|
||||||
// otherwise enable for any non-false value
|
|
||||||
const enabled = mode === 3 ? value === true : value !== false
|
|
||||||
if (__DEV__ && enabled) {
|
if (__DEV__ && enabled) {
|
||||||
warnDeprecation(key, context, loc, ...args)
|
warnDeprecation(key, context, loc, ...args)
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,11 @@ import {
|
|||||||
import { buildSlots } from './vSlot'
|
import { buildSlots } from './vSlot'
|
||||||
import { getConstantType } from './hoistStatic'
|
import { getConstantType } from './hoistStatic'
|
||||||
import { BindingTypes } from '../options'
|
import { BindingTypes } from '../options'
|
||||||
|
import {
|
||||||
|
checkCompatEnabled,
|
||||||
|
CompilerDeprecationTypes,
|
||||||
|
isCompatEnabled
|
||||||
|
} from '../compat/compatConfig'
|
||||||
|
|
||||||
// some directive transforms (e.g. v-model) may return a symbol for runtime
|
// some directive transforms (e.g. v-model) may return a symbol for runtime
|
||||||
// import, which should be used instead of a resolveDirective call.
|
// import, which should be used instead of a resolveDirective call.
|
||||||
@ -450,8 +455,8 @@ export function buildProps(
|
|||||||
} else {
|
} else {
|
||||||
// directives
|
// directives
|
||||||
const { name, arg, exp, loc } = prop
|
const { name, arg, exp, loc } = prop
|
||||||
const isBind = name === 'bind'
|
const isVBind = name === 'bind'
|
||||||
const isOn = name === 'on'
|
const isVOn = name === 'on'
|
||||||
|
|
||||||
// skip v-slot - it is handled by its dedicated transform.
|
// skip v-slot - it is handled by its dedicated transform.
|
||||||
if (name === 'slot') {
|
if (name === 'slot') {
|
||||||
@ -469,17 +474,17 @@ export function buildProps(
|
|||||||
// skip v-is and :is on <component>
|
// skip v-is and :is on <component>
|
||||||
if (
|
if (
|
||||||
name === 'is' ||
|
name === 'is' ||
|
||||||
(isBind && isComponentTag(tag) && isBindKey(arg, 'is'))
|
(isVBind && isComponentTag(tag) && isBindKey(arg, 'is'))
|
||||||
) {
|
) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// skip v-on in SSR compilation
|
// skip v-on in SSR compilation
|
||||||
if (isOn && ssr) {
|
if (isVOn && ssr) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case for v-bind and v-on with no argument
|
// special case for v-bind and v-on with no argument
|
||||||
if (!arg && (isBind || isOn)) {
|
if (!arg && (isVBind || isVOn)) {
|
||||||
hasDynamicKeys = true
|
hasDynamicKeys = true
|
||||||
if (exp) {
|
if (exp) {
|
||||||
if (properties.length) {
|
if (properties.length) {
|
||||||
@ -488,7 +493,49 @@ export function buildProps(
|
|||||||
)
|
)
|
||||||
properties = []
|
properties = []
|
||||||
}
|
}
|
||||||
if (isBind) {
|
if (isVBind) {
|
||||||
|
if (__COMPAT__) {
|
||||||
|
if (__DEV__) {
|
||||||
|
const hasOverridableKeys = mergeArgs.some(arg => {
|
||||||
|
if (arg.type === NodeTypes.JS_OBJECT_EXPRESSION) {
|
||||||
|
return arg.properties.some(({ key }) => {
|
||||||
|
if (
|
||||||
|
key.type !== NodeTypes.SIMPLE_EXPRESSION ||
|
||||||
|
!key.isStatic
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
key.content !== 'class' &&
|
||||||
|
key.content !== 'style' &&
|
||||||
|
!isOn(key.content)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// dynamic expression
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (hasOverridableKeys) {
|
||||||
|
checkCompatEnabled(
|
||||||
|
CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER,
|
||||||
|
context,
|
||||||
|
loc
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
isCompatEnabled(
|
||||||
|
CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
mergeArgs.unshift(exp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mergeArgs.push(exp)
|
mergeArgs.push(exp)
|
||||||
} else {
|
} else {
|
||||||
// v-on="obj" -> toHandlers(obj)
|
// v-on="obj" -> toHandlers(obj)
|
||||||
@ -502,7 +549,7 @@ export function buildProps(
|
|||||||
} else {
|
} else {
|
||||||
context.onError(
|
context.onError(
|
||||||
createCompilerError(
|
createCompilerError(
|
||||||
isBind
|
isVBind
|
||||||
? ErrorCodes.X_V_BIND_NO_EXPRESSION
|
? ErrorCodes.X_V_BIND_NO_EXPRESSION
|
||||||
: ErrorCodes.X_V_ON_NO_EXPRESSION,
|
: ErrorCodes.X_V_ON_NO_EXPRESSION,
|
||||||
loc
|
loc
|
||||||
|
Loading…
Reference in New Issue
Block a user