X_V_FOR_MALFORMED_EXPRESSION,
X_V_FOR_TEMPLATE_KEY_PLACEMENT,
X_V_BIND_NO_EXPRESSION,
+ X_V_BIND_INVALID_SAME_NAME_ARGUMENT,
X_V_ON_NO_EXPRESSION,
X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET,
X_V_SLOT_MIXED_SLOT_USAGE,
[ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION]: `v-for has invalid expression.`,
[ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT]: `<template v-for> key should be placed on the <template> tag.`,
[ErrorCodes.X_V_BIND_NO_EXPRESSION]: `v-bind is missing expression.`,
+ [ErrorCodes.X_V_BIND_INVALID_SAME_NAME_ARGUMENT]: `v-bind with same-name shorthand only allows static argument.`,
[ErrorCodes.X_V_ON_NO_EXPRESSION]: `v-on is missing expression.`,
[ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET]: `Unexpected custom directive on <slot> outlet.`,
[ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE]:
import {
type ExpressionNode,
NodeTypes,
+ type SimpleExpressionNode,
createObjectProperty,
createSimpleExpression,
} from '../ast'
const { modifiers, loc } = dir
const arg = dir.arg!
- // :arg is replaced by :arg="arg"
let { exp } = dir
- if (!exp && arg.type === NodeTypes.SIMPLE_EXPRESSION) {
- const propName = camelize(arg.content)
+
+ // handle empty expression
+ if (exp && exp.type === NodeTypes.SIMPLE_EXPRESSION && !exp.content.trim()) {
+ if (!__BROWSER__) {
+ // #10280 only error against empty expression in non-browser build
+ // because :foo in in-DOM templates will be parsed into :foo="" by the
+ // browser
+ context.onError(
+ createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc),
+ )
+ return {
+ props: [
+ createObjectProperty(arg, createSimpleExpression('', true, loc)),
+ ],
+ }
+ } else {
+ exp = undefined
+ }
+ }
+
+ // same-name shorthand - :arg is expanded to :arg="arg"
+ if (!exp) {
+ if (arg.type !== NodeTypes.SIMPLE_EXPRESSION || !arg.isStatic) {
+ // only simple expression is allowed for same-name shorthand
+ context.onError(
+ createCompilerError(
+ ErrorCodes.X_V_BIND_INVALID_SAME_NAME_ARGUMENT,
+ arg.loc,
+ ),
+ )
+ return {
+ props: [
+ createObjectProperty(arg, createSimpleExpression('', true, loc)),
+ ],
+ }
+ }
+
+ const propName = camelize((arg as SimpleExpressionNode).content)
exp = dir.exp = createSimpleExpression(propName, false, arg.loc)
if (!__BROWSER__) {
exp = dir.exp = processExpression(exp, context)
}
}
- if (
- !exp ||
- (exp.type === NodeTypes.SIMPLE_EXPRESSION && !exp.content.trim())
- ) {
- context.onError(createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc))
- return {
- props: [createObjectProperty(arg, createSimpleExpression('', true, loc))],
- }
- }
-
return {
props: [createObjectProperty(arg, exp)],
}