diff --git a/packages/compiler-core/src/compat/compatConfig.ts b/packages/compiler-core/src/compat/compatConfig.ts index 91acbbd8..712cdd93 100644 --- a/packages/compiler-core/src/compat/compatConfig.ts +++ b/packages/compiler-core/src/compat/compatConfig.ts @@ -16,8 +16,9 @@ export interface CompilerCompatOptions { export const enum CompilerDeprecationTypes { COMPILER_IS_ON_ELEMENT = 'COMPILER_IS_ON_ELEMENT', COMPILER_V_BIND_SYNC = 'COMPILER_V_BIND_SYNC', + COMPILER_V_BIND_PROP = 'COMPILER_V_BIND_PROP', COMPILER_V_BIND_OBJECT_ORDER = 'COMPILER_V_BIND_OBJECT_ORDER', - COMPILER_V_ON_NATIVE_MODIFIER = 'COMPILER_V_ON_NATIVE_MODIFIER', + COMPILER_V_ON_NATIVE = 'COMPILER_V_ON_NATIVE', COMPILER_KEY_V_IF = 'COMPILER_KEY_V_IF', COMPILER_KEY_V_FOR_TEMPLATE = 'COMPILER_KEY_V_FOR_TEMPLATE', COMPILER_V_IF_V_FOR_PRECEDENCE = 'COMPILER_V_IF_V_FOR_PRECEDENCE', @@ -46,6 +47,12 @@ const deprecationData: Record = { link: `https://v3.vuejs.org/guide/migration/v-model.html` }, + [CompilerDeprecationTypes.COMPILER_V_BIND_PROP]: { + message: + `.prop modifier for v-bind has been removed and no longer necessary. ` + + `Vue 3 will automatically set a binding as DOM property when appropriate.` + }, + [CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER]: { message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` + @@ -56,7 +63,7 @@ const deprecationData: Record = { link: `https://v3.vuejs.org/guide/migration/v-bind.html` }, - [CompilerDeprecationTypes.COMPILER_V_ON_NATIVE_MODIFIER]: { + [CompilerDeprecationTypes.COMPILER_V_ON_NATIVE]: { message: `.native modifier for v-on has been removed as is no longer necessary.`, link: `https://v3.vuejs.org/guide/migration/v-on-native-modifier-removed.html` }, diff --git a/packages/compiler-core/src/parse.ts b/packages/compiler-core/src/parse.ts index 055d76b1..1e7d9701 100644 --- a/packages/compiler-core/src/parse.ts +++ b/packages/compiler-core/src/parse.ts @@ -650,10 +650,9 @@ function parseAttribute( name )! - const dirName = + let dirName = match[1] || (startsWith(name, ':') ? 'bind' : startsWith(name, '@') ? 'on' : 'slot') - let arg: ExpressionNode | undefined if (match[2]) { @@ -708,6 +707,25 @@ function parseAttribute( valueLoc.source = valueLoc.source.slice(1, -1) } + const modifiers = match[3] ? match[3].substr(1).split('.') : [] + + // 2.x compat v-bind:foo.sync -> v-model:foo + if ( + __COMPAT__ && + dirName === 'bind' && + arg && + modifiers.includes('sync') && + checkCompatEnabled( + CompilerDeprecationTypes.COMPILER_V_BIND_SYNC, + context, + loc, + arg.loc.source + ) + ) { + dirName = 'model' + modifiers.splice(modifiers.indexOf('sync'), 1) + } + return { type: NodeTypes.DIRECTIVE, name: dirName, @@ -721,7 +739,7 @@ function parseAttribute( loc: value.loc }, arg, - modifiers: match[3] ? match[3].substr(1).split('.') : [], + modifiers, loc } } diff --git a/packages/compiler-core/src/transforms/vBind.ts b/packages/compiler-core/src/transforms/vBind.ts index 0d31a266..acfe695e 100644 --- a/packages/compiler-core/src/transforms/vBind.ts +++ b/packages/compiler-core/src/transforms/vBind.ts @@ -3,11 +3,15 @@ import { createObjectProperty, createSimpleExpression, NodeTypes } from '../ast' import { createCompilerError, ErrorCodes } from '../errors' import { camelize } from '@vue/shared' import { CAMELIZE } from '../runtimeHelpers' +import { + checkCompatEnabled, + CompilerDeprecationTypes +} from '../compat/compatConfig' // v-bind without arg is handled directly in ./transformElements.ts due to it affecting // codegen for the entire props object. This transform here is only for v-bind // *with* args. -export const transformBind: DirectiveTransform = (dir, node, context) => { +export const transformBind: DirectiveTransform = (dir, _node, context) => { const { exp, modifiers, loc } = dir const arg = dir.arg! @@ -33,6 +37,18 @@ export const transformBind: DirectiveTransform = (dir, node, context) => { } } + if (__COMPAT__) { + if (modifiers.includes('prop')) { + checkCompatEnabled( + CompilerDeprecationTypes.COMPILER_V_BIND_PROP, + context, + loc + ) + } + // .sync handling is performed directly in the parse phase to transform + // it into v-model:arg equivalent. + } + if ( !exp || (exp.type === NodeTypes.SIMPLE_EXPRESSION && !exp.content.trim()) diff --git a/packages/compiler-dom/src/transforms/vOn.ts b/packages/compiler-dom/src/transforms/vOn.ts index 7ce57dfa..7ff4b7b6 100644 --- a/packages/compiler-dom/src/transforms/vOn.ts +++ b/packages/compiler-dom/src/transforms/vOn.ts @@ -96,7 +96,7 @@ export const transformOn: DirectiveTransform = (dir, node, context) => { if (__COMPAT__ && __DEV__ && modifiers.includes('native')) { warnDeprecation( - CompilerDeprecationTypes.COMPILER_V_ON_NATIVE_MODIFIER, + CompilerDeprecationTypes.COMPILER_V_ON_NATIVE, context, dir.loc )