fix(compiler-core): support v-bind shorthand syntax for dynamic slot name (#10218)

close #10213
This commit is contained in:
zhoulixiang 2024-02-06 17:54:06 +08:00 committed by GitHub
parent f0b5f7ed8d
commit 91f058a90c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 1 deletions

View File

@ -389,4 +389,20 @@ describe('compiler: transform <slot> outlets', () => {
}, },
}) })
}) })
test('dynamically named slot outlet with v-bind shorthand', () => {
const ast = parseWithSlots(`<slot :name />`)
expect((ast.children[0] as ElementNode).codegenNode).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT,
arguments: [
`$slots`,
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `name`,
isStatic: false,
},
],
})
})
}) })

View File

@ -6,12 +6,14 @@ import {
type SlotOutletNode, type SlotOutletNode,
createCallExpression, createCallExpression,
createFunctionExpression, createFunctionExpression,
createSimpleExpression,
} from '../ast' } from '../ast'
import { isSlotOutlet, isStaticArgOf, isStaticExp } from '../utils' import { isSlotOutlet, isStaticArgOf, isStaticExp } from '../utils'
import { type PropsExpression, buildProps } from './transformElement' import { type PropsExpression, buildProps } from './transformElement'
import { ErrorCodes, createCompilerError } from '../errors' import { ErrorCodes, createCompilerError } from '../errors'
import { RENDER_SLOT } from '../runtimeHelpers' import { RENDER_SLOT } from '../runtimeHelpers'
import { camelize } from '@vue/shared' import { camelize } from '@vue/shared'
import { processExpression } from './transformExpression'
export const transformSlotOutlet: NodeTransform = (node, context) => { export const transformSlotOutlet: NodeTransform = (node, context) => {
if (isSlotOutlet(node)) { if (isSlotOutlet(node)) {
@ -76,7 +78,15 @@ export function processSlotOutlet(
} }
} else { } else {
if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) { if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
if (p.exp) slotName = p.exp if (p.exp) {
slotName = p.exp
} else if (p.arg && p.arg.type === NodeTypes.SIMPLE_EXPRESSION) {
const name = camelize(p.arg.content)
slotName = p.exp = createSimpleExpression(name, false, p.arg.loc)
if (!__BROWSER__) {
slotName = p.exp = processExpression(p.exp, context)
}
}
} else { } else {
if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) { if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
p.arg.content = camelize(p.arg.content) p.arg.content = camelize(p.arg.content)