diff --git a/packages/compiler-core/__tests__/transforms/vOn.spec.ts b/packages/compiler-core/__tests__/transforms/vOn.spec.ts index 568fa0b5a8c..b1c37e3f74e 100644 --- a/packages/compiler-core/__tests__/transforms/vOn.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vOn.spec.ts @@ -286,6 +286,23 @@ describe('compiler: transform v-on', () => { }) }) + test('should NOT wrap as function if expression is already function expression (async)', () => { + const { node } = parseWithVOn( + `
`, + ) + expect((node.codegenNode as VNodeCall).props).toMatchObject({ + properties: [ + { + key: { content: `onClick` }, + value: { + type: NodeTypes.SIMPLE_EXPRESSION, + content: `async $event => await foo($event)`, + }, + }, + ], + }) + }) + test('should NOT wrap as function if expression is already function expression (with newlines)', () => { const { node } = parseWithVOn( `
await foo(e)" />`, + { + prefixIdentifiers: true, + cacheHandlers: true, + }, + ) + + expect(root.cached).toBe(1) + const vnodeCall = node.codegenNode as VNodeCall + // should not treat cached handler as dynamicProp, so no flags + expect(vnodeCall.patchFlag).toBeUndefined() + expect( + (vnodeCall.props as ObjectExpression).properties[0].value, + ).toMatchObject({ + type: NodeTypes.JS_CACHE_EXPRESSION, + index: 0, + value: { + type: NodeTypes.COMPOUND_EXPRESSION, + children: [ + `async `, + { content: `e` }, + ` => await `, + { content: `_ctx.foo` }, + `(`, + { content: `e` }, + `)`, + ], + }, + }) + }) + test('inline async function expression handler', () => { const { root, node } = parseWithVOn( `
`, diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts index 8c13bdae524..a1631e10db3 100644 --- a/packages/compiler-core/src/transforms/vOn.ts +++ b/packages/compiler-core/src/transforms/vOn.ts @@ -17,7 +17,7 @@ import { hasScopeRef, isMemberExpression } from '../utils' import { TO_HANDLER_KEY } from '../runtimeHelpers' const fnExpRE = - /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/ + /^\s*(async\s*)?(\([^)]*?\)|[\w$_]+)\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/ export interface VOnDirectiveNode extends DirectiveNode { // v-on without arg is handled directly in ./transformElements.ts due to it affecting