},
})
})
+
+ 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,
+ },
+ ],
+ })
+ })
})
type SlotOutletNode,
createCallExpression,
createFunctionExpression,
+ createSimpleExpression,
} from '../ast'
import { isSlotOutlet, isStaticArgOf, isStaticExp } from '../utils'
import { type PropsExpression, buildProps } from './transformElement'
import { ErrorCodes, createCompilerError } from '../errors'
import { RENDER_SLOT } from '../runtimeHelpers'
import { camelize } from '@vue/shared'
+import { processExpression } from './transformExpression'
export const transformSlotOutlet: NodeTransform = (node, context) => {
if (isSlotOutlet(node)) {
}
} else {
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 {
if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
p.arg.content = camelize(p.arg.content)