mirror of https://github.com/vuejs/core.git
fix(compiler-core): handle same-name shorthand edge case for in-DOM templates
Also add error for invalid arguments for same-name shorthand. close #10280
This commit is contained in:
parent
0bced13ee5
commit
cb87b6213d
|
@ -408,4 +408,22 @@ describe('compiler: transform v-bind', () => {
|
|||
},
|
||||
})
|
||||
})
|
||||
|
||||
test('error on invalid argument for same-name shorthand', () => {
|
||||
const onError = vi.fn()
|
||||
parseWithVBind(`<div v-bind:[arg] />`, { onError })
|
||||
expect(onError.mock.calls[0][0]).toMatchObject({
|
||||
code: ErrorCodes.X_V_BIND_INVALID_SAME_NAME_ARGUMENT,
|
||||
loc: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 13,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 18,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -78,6 +78,7 @@ export enum ErrorCodes {
|
|||
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,
|
||||
|
@ -156,6 +157,7 @@ export const errorMessages: Record<ErrorCodes, string> = {
|
|||
[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]:
|
||||
|
|
|
@ -2,6 +2,7 @@ import type { DirectiveTransform } from '../transform'
|
|||
import {
|
||||
type ExpressionNode,
|
||||
NodeTypes,
|
||||
type SimpleExpressionNode,
|
||||
createObjectProperty,
|
||||
createSimpleExpression,
|
||||
} from '../ast'
|
||||
|
@ -17,10 +18,45 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => {
|
|||
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)
|
||||
|
@ -57,16 +93,6 @@ export const transformBind: DirectiveTransform = (dir, _node, 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)],
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue