fix(compiler-core): fix v-bind shorthand handling for in-DOM templates (#13933)

close #13930
This commit is contained in:
edison 2025-11-05 16:51:29 +08:00 committed by GitHub
parent 8ec7cb12e4
commit b3cca2611c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 2 deletions

View File

@ -112,6 +112,27 @@ describe('compiler: transform v-bind', () => {
}) })
}) })
test('no expression (shorthand) in-DOM templates', () => {
try {
__BROWSER__ = true
// :id in in-DOM templates will be parsed into :id="" by browser
const node = parseWithVBind(`<div :id="" />`)
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(props.properties[0]).toMatchObject({
key: {
content: `id`,
isStatic: true,
},
value: {
content: `id`,
isStatic: false,
},
})
} finally {
__BROWSER__ = false
}
})
test('dynamic arg', () => { test('dynamic arg', () => {
const node = parseWithVBind(`<div v-bind:[id]="id"/>`) const node = parseWithVBind(`<div v-bind:[id]="id"/>`)
const props = (node.codegenNode as VNodeCall).props as CallExpression const props = (node.codegenNode as VNodeCall).props as CallExpression

View File

@ -1054,7 +1054,7 @@ export function baseParse(input: string, options?: ParserOptions): RootNode {
`[@vue/compiler-core] decodeEntities option is passed but will be ` + `[@vue/compiler-core] decodeEntities option is passed but will be ` +
`ignored in non-browser builds.`, `ignored in non-browser builds.`,
) )
} else if (__BROWSER__ && !currentOptions.decodeEntities) { } else if (__BROWSER__ && !__TEST__ && !currentOptions.decodeEntities) {
throw new Error( throw new Error(
`[@vue/compiler-core] decodeEntities option is required in browser builds.`, `[@vue/compiler-core] decodeEntities option is required in browser builds.`,
) )

View File

@ -15,7 +15,11 @@ export const transformVBindShorthand: NodeTransform = (node, context) => {
if ( if (
prop.type === NodeTypes.DIRECTIVE && prop.type === NodeTypes.DIRECTIVE &&
prop.name === 'bind' && prop.name === 'bind' &&
!prop.exp (!prop.exp ||
// #13930 :foo in in-DOM templates will be parsed into :foo="" by browser
(__BROWSER__ &&
prop.exp.type === NodeTypes.SIMPLE_EXPRESSION &&
!prop.exp.content.trim()))
) { ) {
const arg = prop.arg! const arg = prop.arg!
if (arg.type !== NodeTypes.SIMPLE_EXPRESSION || !arg.isStatic) { if (arg.type !== NodeTypes.SIMPLE_EXPRESSION || !arg.isStatic) {